<!DOCTYPE html>
<!-- saved from url=(0016)http://localhost -->
<html>
  <head>
    <meta charset="utf-8"/>
    <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
    <title>设计模式之美2-创建型</title>
    <style>
        body{
            margin: 0;
        }
        #content-info{
            width: auto;
            margin: 0 auto;
            text-align: center;
        }
        #author-info{
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
        }
        #title{
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            padding-top: 10px;
            margin-bottom: 2px;
            font-size: 34px;
            color: #505050;
        }
        .text{
            white-space:nowrap;
            text-overflow: ellipsis;
            display: inline-block;
            margin-right: 20px;
            margin-bottom: 2px;
            font-size: 20px;
            color: #8c8c8c;
        }
        #navBar{
            width: auto;
            height: auto;
            position: fixed;
            right:0;
            bottom: 0;
            background-color: #f0f3f4;
            overflow-y: auto;
            text-align: center;
        }
        #svg-container{
            width: 100%;
            overflow-x: scroll;
            min-width: 0px;
            margin: 0 10px;
        }
        #nav-thumbs{
            overflow-y: scroll;
            padding: 0 5px;
        }
        .nav-thumb{
            position: relative;
            margin: 10px auto;
        }
        .nav-thumb >p{
            text-align: center;
            font-size: 12px;
            margin: 4px 0 0 0;
        }
        .nav-thumb >div{
            position: relative;
            display: inline-block;
            border: 1px solid #c6cfd5;
        }
        .nav-thumb img{
            display: block;
        }
        #main-content{
            bottom: 0;
            left: 0;
            right: 0;
            background-color: #d0cfd8;
            display: flex;
            height: auto;
            flex-flow: row wrap;
            text-align:center;
        }
        #svg-container >svg{
            display: block;
            margin:10px auto;
            margin-bottom: 0;
        }
        #copyright{
            bottom: 0;
            left: 50%;
            margin: 5px auto;
            font-size: 16px;
            color: #515151;
        }
        #copyright >a{
            text-decoration: none;
            color: #77C;
        }
        .number{
            position: absolute;
            top:0;
            left:0;
            border-top:22px solid #08a1ef;
            border-right: 22px solid transparent;
        }
        .pagenum{
            font-size: 12px;
            color: #fff;
            position: absolute;
            top: -23px;
            left: 2px;
        }
            #navBar::-webkit-scrollbar{
            width: 8px;
            background-color: #f5f5f5;
        }
            #navBar::-webkit-scrollbar-track{
            -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.3);
            border-radius: 8px;
            background-color: #fff;
        }
            #navBar::-webkit-scrollbar-thumb{
            border-radius: 8px;
            -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.3);
            background-color: #6b6b70;
        }
        #navBar::-webkit-scrollbar-thumb:hover{
            background-color: #4a4a4f;
        }
</style>
  </head>
  <body>
    <div id="main-area">
      <div id="content-info">
        <div id="content-info">
          <div id="title">设计模式之美2-创建型</div>
        </div>
        <div id="author-info">
          <div id="author-name" class="text">sangjiacun</div>
          <div id="share-time" class="text">2020-05-14</div>
        </div>
      </div>
      <div id="main-content">
        <div id="svg-container"><svg ed:name="Page-1" xmlns="http://www.w3.org/2000/svg" width="3612" xmlns:xlink="http://www.w3.org/1999/xlink" height="4124" ed:hSpacing="30" xmlns:ev="http://www.w3.org/2001/xml-events" ed:vSpacing="30" id="page1" preserveAspectRadio="xMinYMin meet" xmlns:ed="https://www.edrawsoft.cn/xml/2017/SVGExtensions/" viewBox="0 0 3612 4124">
    <style type="text/css"><![CDATA[
g[ed\:togtopicid],g[ed\:hyperlink],g[ed\:comment],g[ed\:note] {cursor:pointer;}
g[id] {-moz-user-select: none;-ms-user-select: none;user-select: none;}
svg text::selection,svg tspan::selection{background-color: #4285f4;color: #ffffff;fill: #ffffff;}
.st16 {fill:#000000}
.st12 {fill:#00b050;font-weight:normal}
.st14 {fill:#00b0f0}
.st5 {fill:#01928f;font-family:宋体;font-size:9pt}
.st8 {fill:#01928f}
.st3 {fill:#303030;font-family:宋体;font-size:11.25pt}
.st9 {fill:#3498db}
.st1 {fill:#454545;font-family:宋体;font-size:9pt}
.st11 {fill:#454545;font-weight:normal}
.st6 {fill:#454545}
.st15 {fill:#ff0000;font-family:宋体;font-size:11.25pt}
.st10 {fill:#ff0000;font-family:宋体;font-size:9pt;font-weight:bold}
.st7 {fill:#ff0000;font-family:宋体;font-size:9pt}
.st4 {fill:#ff0000}
.st2 {fill:#ffffff;font-family:宋体;font-size:14.25pt}
.st13 {font-weight:normal}
]]></style>
    <defs>
        <linearGradient id="lg1" x2="0%" x1="0%" y1="0%" y2="100%">
            <stop offset="0" stop-color="#ffffff"/>
            <stop offset="0.25" stop-color="#f0f5f0"/>
            <stop offset="0.75" stop-color="#e1ebe1"/>
            <stop offset="1" stop-color="#c8d7c8"/>
        </linearGradient>
    </defs>
    <rect width="3612" height="4124" fill="#ffffff" y="0" x="0"/>
    <path ed:tosuperid="102" stroke-linecap="round" fill="none" d="M35.8,242.9L63.8,242.9L63.8,-242.9L98.8,-242.9" id="103" transform="matrix(1,0,0,1,1776,1819)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="104" stroke-linecap="round" fill="none" d="M3.7,513.1L3.7,-513.1L13.5,-513.1" id="105" transform="matrix(1,0,0,1,2012,1063)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="107" stroke-linecap="round" fill="none" d="M-35.8,222.9L-63.8,222.9L-63.8,-222.9L-98.8,-222.9" id="108" transform="matrix(1,0,0,1,1578,1839)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="109" stroke-linecap="round" fill="none" d="M35.8,-561.8L63.8,-561.8L63.8,561.8L98.8,561.8" id="110" transform="matrix(1,0,0,1,1776,2624)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="111" stroke-linecap="round" fill="none" d="M-35.8,-805.8L-63.8,-805.8L-63.8,805.8L-98.8,805.8" id="112" transform="matrix(1,0,0,1,1578,2868)" stroke="#696969" stroke-linejoin="round" ed:parentid="101"/>
    <path ed:tosuperid="151" stroke-linecap="round" fill="none" d="M-13.5,533.4L3.7,533.4L3.7,-533.4L13.5,-533.4" id="152" transform="matrix(1,0,0,1,2012,1043)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="153" stroke-linecap="round" fill="none" d="M-13.5,6.8L3.7,6.8L3.7,-6.8L13.5,-6.8" id="154" transform="matrix(1,0,0,1,2165,543)" stroke="#696969" stroke-linejoin="round" ed:parentid="104"/>
    <path ed:tosuperid="155" stroke-linecap="round" fill="none" d="M3.7,-6.8L3.7,6.8L13.5,6.8" id="156" transform="matrix(1,0,0,1,2165,556)" stroke="#696969" stroke-linejoin="round" ed:parentid="104"/>
    <path ed:tosuperid="157" stroke-linecap="round" fill="none" d="M3.7,296.6L3.7,-296.6L13.5,-296.6" id="158" transform="matrix(1,0,0,1,2012,1279)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="159" stroke-linecap="round" fill="none" d="M-13.5,20.3L3.7,20.3L3.7,-20.3L13.5,-20.3" id="160" transform="matrix(1,0,0,1,2258,610)" stroke="#696969" stroke-linejoin="round" ed:parentid="167"/>
    <path ed:tosuperid="161" stroke-linecap="round" fill="none" d="M3.7,6.8L3.7,-6.8L13.5,-6.8" id="162" transform="matrix(1,0,0,1,2258,624)" stroke="#696969" stroke-linejoin="round" ed:parentid="167"/>
    <path ed:tosuperid="163" stroke-linecap="round" fill="none" d="M3.7,-6.8L3.7,6.8L13.5,6.8" id="164" transform="matrix(1,0,0,1,2258,637)" stroke="#696969" stroke-linejoin="round" ed:parentid="167"/>
    <path ed:tosuperid="165" stroke-linecap="round" fill="none" d="M3.7,-20.3L3.7,20.3L13.5,20.3" id="166" transform="matrix(1,0,0,1,2258,651)" stroke="#696969" stroke-linejoin="round" ed:parentid="167"/>
    <path ed:tosuperid="167" stroke-linecap="round" fill="none" d="M-13.5,176L3.7,176L3.7,-176L13.5,-176" id="168" transform="matrix(1,0,0,1,2165,807)" stroke="#696969" stroke-linejoin="round" ed:parentid="157"/>
    <path ed:tosuperid="169" stroke-linecap="round" fill="none" d="M3.7,106.9L3.7,-106.9L13.5,-106.9" id="170" transform="matrix(1,0,0,1,2165,876)" stroke="#696969" stroke-linejoin="round" ed:parentid="157"/>
    <path ed:tosuperid="171" stroke-linecap="round" fill="none" d="M3.7,-7.4L3.7,7.4L13.5,7.4" id="172" transform="matrix(1,0,0,1,2265,776)" stroke="#696969" stroke-linejoin="round" ed:parentid="169"/>
    <path ed:tosuperid="173" stroke-linecap="round" fill="none" d="M3.7,-20.9L3.7,20.9L13.5,20.9" id="174" transform="matrix(1,0,0,1,2265,790)" stroke="#696969" stroke-linejoin="round" ed:parentid="169"/>
    <path ed:tosuperid="175" stroke-linecap="round" fill="none" d="M3.7,19.1L3.7,-19.1L13.5,-19.1" id="176" transform="matrix(1,0,0,1,2165,964)" stroke="#696969" stroke-linejoin="round" ed:parentid="157"/>
    <path ed:tosuperid="177" stroke-linecap="round" fill="none" d="M3.7,-34.4L3.7,34.4L13.5,34.4" id="178" transform="matrix(1,0,0,1,2265,803)" stroke="#696969" stroke-linejoin="round" ed:parentid="169"/>
    <path ed:tosuperid="179" stroke-linecap="round" fill="none" d="M-13.5,25.9L3.7,25.9L3.7,-25.9L13.5,-25.9" id="180" transform="matrix(1,0,0,1,2265,743)" stroke="#696969" stroke-linejoin="round" ed:parentid="169"/>
    <path ed:tosuperid="181" stroke-linecap="round" fill="none" d="M3.7,-25.4L3.7,25.4L13.5,25.4" id="182" transform="matrix(1,0,0,1,2265,970)" stroke="#696969" stroke-linejoin="round" ed:parentid="175"/>
    <path ed:tosuperid="183" stroke-linecap="round" fill="none" d="M-13.5,19.1L3.7,19.1L3.7,-19.1L13.5,-19.1" id="184" transform="matrix(1,0,0,1,2265,925)" stroke="#696969" stroke-linejoin="round" ed:parentid="175"/>
    <path ed:tosuperid="185" stroke-linecap="round" fill="none" d="M3.7,-38.9L3.7,38.9L13.5,38.9" id="186" transform="matrix(1,0,0,1,2265,983)" stroke="#696969" stroke-linejoin="round" ed:parentid="175"/>
    <path ed:tosuperid="187" stroke-linecap="round" fill="none" d="M3.7,-78.9L3.7,78.9L13.5,78.9" id="188" transform="matrix(1,0,0,1,2165,1062)" stroke="#696969" stroke-linejoin="round" ed:parentid="157"/>
    <path ed:tosuperid="189" stroke-linecap="round" fill="none" d="M-13.5,5.6L3.7,5.6L3.7,-5.6L13.5,-5.6" id="190" transform="matrix(1,0,0,1,2277,1135)" stroke="#696969" stroke-linejoin="round" ed:parentid="187"/>
    <path ed:tosuperid="191" stroke-linecap="round" fill="none" d="M3.7,-167.1L3.7,167.1L13.5,167.1" id="192" transform="matrix(1,0,0,1,2165,1150)" stroke="#696969" stroke-linejoin="round" ed:parentid="157"/>
    <path ed:tosuperid="193" stroke-linecap="round" fill="none" d="M-13.5,5.6L3.7,5.6L3.7,-5.6L13.5,-5.6" id="194" transform="matrix(1,0,0,1,2289,1311)" stroke="#696969" stroke-linejoin="round" ed:parentid="191"/>
    <path ed:tosuperid="195" stroke-linecap="round" fill="none" d="M3.7,-8.6L3.7,8.6L13.5,8.6" id="196" transform="matrix(1,0,0,1,2012,1585)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="197" stroke-linecap="round" fill="none" d="M-13.5,73.5L3.7,73.5L3.7,-73.5L13.5,-73.5" id="198" transform="matrix(1,0,0,1,2158,1520)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="199" stroke-linecap="round" fill="none" d="M-13.5,22L3.7,22L3.7,-22L13.5,-22" id="200" transform="matrix(1,0,0,1,2383,1424)" stroke="#696969" stroke-linejoin="round" ed:parentid="197"/>
    <path ed:tosuperid="201" stroke-linecap="round" fill="none" d="M3.7,0L13.5,0" id="202" transform="matrix(1,0,0,1,2383,1446)" stroke="#696969" stroke-linejoin="round" ed:parentid="197"/>
    <path ed:tosuperid="203" stroke-linecap="round" fill="none" d="M3.7,-22L3.7,22L13.5,22" id="204" transform="matrix(1,0,0,1,2383,1468)" stroke="#696969" stroke-linejoin="round" ed:parentid="197"/>
    <path ed:tosuperid="205" stroke-linecap="round" fill="none" d="M3.7,33.8L3.7,-33.8L13.5,-33.8" id="206" transform="matrix(1,0,0,1,2158,1559)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="207" stroke-linecap="round" fill="none" d="M-13.5,-4.3L3.7,-4.3L3.7,4.3L13.5,4.3" id="208" transform="matrix(1,0,0,1,2374,1530)" stroke="#696969" stroke-linejoin="round" ed:parentid="205"/>
    <path ed:tosuperid="209" stroke-linecap="round" fill="none" d="M3.7,9.3L3.7,-9.3L13.5,-9.3" id="210" transform="matrix(1,0,0,1,2158,1584)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="211" stroke-linecap="round" fill="none" d="M-13.5,6.8C-1.1,6.8,1.7,-6.8,13.5,-6.8" id="212" transform="matrix(1,0,0,1,2362,1568)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="213" stroke-linecap="round" fill="none" d="M-13.5,-6.8C-1.1,-6.8,1.7,6.8,13.5,6.8" id="214" transform="matrix(1,0,0,1,2362,1581)" stroke="#696969" stroke-linejoin="round" ed:parentid="209"/>
    <path ed:tosuperid="215" stroke-linecap="round" fill="none" d="M3.7,-26.3L3.7,26.3L13.5,26.3" id="216" transform="matrix(1,0,0,1,2158,1619)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="217" stroke-linecap="round" fill="none" d="M-13.5,15.3C0.8,15.3,-2.7,-15.3,13.5,-15.3" id="218" transform="matrix(1,0,0,1,2374,1630)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="219" stroke-linecap="round" fill="none" d="M-13.5,-15.3C0.8,-15.3,-2.7,15.3,13.5,15.3" id="220" transform="matrix(1,0,0,1,2374,1661)" stroke="#696969" stroke-linejoin="round" ed:parentid="215"/>
    <path ed:tosuperid="221" stroke-linecap="round" fill="none" d="M3.7,-75.3L3.7,75.3L13.5,75.3" id="222" transform="matrix(1,0,0,1,2158,1668)" stroke="#696969" stroke-linejoin="round" ed:parentid="195"/>
    <path ed:tosuperid="223" stroke-linecap="round" fill="none" d="M-13.5,20.3C1.8,20.3,-5.1,-20.3,13.5,-20.3" id="224" transform="matrix(1,0,0,1,2374,1723)" stroke="#696969" stroke-linejoin="round" ed:parentid="221"/>
    <path ed:tosuperid="225" stroke-linecap="round" fill="none" d="M-13.5,-6.8C-1.1,-6.8,1.7,6.8,13.5,6.8" id="226" transform="matrix(1,0,0,1,2374,1750)" stroke="#696969" stroke-linejoin="round" ed:parentid="221"/>
    <path ed:tosuperid="227" stroke-linecap="round" fill="none" d="M-13.5,13.5C0.4,13.5,-1.8,-13.5,13.5,-13.5" id="228" transform="matrix(1,0,0,1,2523,1744)" stroke="#696969" stroke-linejoin="round" ed:parentid="225"/>
    <path ed:tosuperid="229" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="230" transform="matrix(1,0,0,1,2523,1757)" stroke="#696969" stroke-linejoin="round" ed:parentid="225"/>
    <path ed:tosuperid="231" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="232" transform="matrix(1,0,0,1,2755,1757)" stroke="#696969" stroke-linejoin="round" ed:parentid="229"/>
    <path ed:tosuperid="233" stroke-linecap="round" fill="none" d="M-13.5,-13.5C0.4,-13.5,-1.8,13.5,13.5,13.5" id="234" transform="matrix(1,0,0,1,2523,1771)" stroke="#696969" stroke-linejoin="round" ed:parentid="225"/>
    <path ed:tosuperid="236" stroke-linecap="round" fill="none" d="M3.7,-131.1L3.7,131.1L13.5,131.1" id="237" transform="matrix(1,0,0,1,2012,1707)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="240" stroke-linecap="round" fill="none" d="M-13.5,13.5C0.4,13.5,-1.8,-13.5,13.5,-13.5" id="241" transform="matrix(1,0,0,1,2165,1825)" stroke="#696969" stroke-linejoin="round" ed:parentid="236"/>
    <path ed:tosuperid="242" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="243" transform="matrix(1,0,0,1,2306,1811)" stroke="#696969" stroke-linejoin="round" ed:parentid="240"/>
    <path ed:tosuperid="244" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="245" transform="matrix(1,0,0,1,2165,1838)" stroke="#696969" stroke-linejoin="round" ed:parentid="236"/>
    <path ed:tosuperid="246" stroke-linecap="round" fill="none" d="M-13.5,-13.5C0.4,-13.5,-1.8,13.5,13.5,13.5" id="247" transform="matrix(1,0,0,1,2165,1852)" stroke="#696969" stroke-linejoin="round" ed:parentid="236"/>
    <path ed:tosuperid="248" stroke-linecap="round" fill="none" d="M3.7,-226.8L3.7,226.8L13.5,226.8" id="249" transform="matrix(1,0,0,1,2012,1803)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="250" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="251" transform="matrix(1,0,0,1,2330,2035)" stroke="#696969" stroke-linejoin="round" ed:parentid="252"/>
    <path ed:tosuperid="252" stroke-linecap="round" fill="none" d="M-13.5,-2.6C-2.1,-2.6,4,2.6,13.5,2.6" id="253" transform="matrix(1,0,0,1,2225,2032)" stroke="#696969" stroke-linejoin="round" ed:parentid="248"/>
    <path ed:tosuperid="254" stroke-linecap="round" fill="none" d="M-13.5,39.8C4.7,39.8,-11.9,-39.8,13.5,-39.8" id="255" transform="matrix(1,0,0,1,2225,1990)" stroke="#696969" stroke-linejoin="round" ed:parentid="248"/>
    <path ed:tosuperid="256" stroke-linecap="round" fill="none" d="M-13.5,28.9C3.3,28.9,-8.7,-28.9,13.5,-28.9" id="257" transform="matrix(1,0,0,1,2330,1921)" stroke="#696969" stroke-linejoin="round" ed:parentid="254"/>
    <path ed:tosuperid="258" stroke-linecap="round" fill="none" d="M-13.5,-42.4C4.9,-42.4,-12.4,42.4,13.5,42.4" id="259" transform="matrix(1,0,0,1,2225,2072)" stroke="#696969" stroke-linejoin="round" ed:parentid="248"/>
    <path ed:tosuperid="260" stroke-linecap="round" fill="none" d="M-13.5,26.3C2.9,26.3,-7.7,-26.3,13.5,-26.3" id="261" transform="matrix(1,0,0,1,2378,2088)" stroke="#696969" stroke-linejoin="round" ed:parentid="258"/>
    <path ed:tosuperid="262" stroke-linecap="round" fill="none" d="M-13.5,-1.6C-2.3,-1.6,4.5,1.6,13.5,1.6" id="263" transform="matrix(1,0,0,1,2330,1952)" stroke="#696969" stroke-linejoin="round" ed:parentid="254"/>
    <path ed:tosuperid="264" stroke-linecap="round" fill="none" d="M-13.5,4.3C-1.7,4.3,3.1,-4.3,13.5,-4.3" id="265" transform="matrix(1,0,0,1,2378,2110)" stroke="#696969" stroke-linejoin="round" ed:parentid="258"/>
    <path ed:tosuperid="266" stroke-linecap="round" fill="none" d="M-13.5,-26.3C2.9,-26.3,-7.7,26.3,13.5,26.3" id="267" transform="matrix(1,0,0,1,2378,2140)" stroke="#696969" stroke-linejoin="round" ed:parentid="258"/>
    <path ed:tosuperid="268" stroke-linecap="round" fill="none" d="M3.7,-426.8L3.7,426.8L13.5,426.8" id="269" transform="matrix(1,0,0,1,2012,2003)" stroke="#696969" stroke-linejoin="round" ed:parentid="102"/>
    <path ed:tosuperid="270" stroke-linecap="round" fill="none" d="M-13.5,117.9C5.4,117.9,-13.5,-117.9,13.5,-117.9" id="271" transform="matrix(1,0,0,1,2208,2312)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="272" stroke-linecap="round" fill="none" d="M-13.5,12.4C0.2,12.4,-1.3,-12.4,13.5,-12.4" id="273" transform="matrix(1,0,0,1,2208,2417)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="274" stroke-linecap="round" fill="none" d="M-13.5,-103.4C5.4,-103.4,-13.5,103.4,13.5,103.4" id="275" transform="matrix(1,0,0,1,2208,2533)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="276" stroke-linecap="round" fill="none" d="M-13.5,-116.9C5.4,-116.9,-13.5,116.9,13.5,116.9" id="277" transform="matrix(1,0,0,1,2208,2546)" stroke="#696969" stroke-linejoin="round" ed:parentid="268"/>
    <path ed:tosuperid="278" stroke-linecap="round" fill="none" d="M13.5,738.8L-3.7,738.8L-3.7,-738.8L-13.5,-738.8" id="279" transform="matrix(1,0,0,1,1343,877)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="280" stroke-linecap="round" fill="none" d="M-3.7,552.9L-3.7,-552.9L-13.5,-552.9" id="281" transform="matrix(1,0,0,1,1343,1063)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="282" stroke-linecap="round" fill="none" d="M-3.7,288.1L-3.7,-288.1L-13.5,-288.1" id="283" transform="matrix(1,0,0,1,1343,1328)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="292" stroke-linecap="round" fill="none" d="M-3.7,-352L-3.7,352L-13.5,352" id="293" transform="matrix(1,0,0,1,1343,1968)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="294" stroke-linecap="round" fill="none" d="M13.5,351.8C-5.4,351.8,13.5,-351.8,-13.5,-351.8" id="295" transform="matrix(1,0,0,1,1157,1968)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="296" stroke-linecap="round" fill="none" d="M13.5,-82.8C-5.4,-82.8,13.5,82.8,-13.5,82.8" id="297" transform="matrix(1,0,0,1,1157,2403)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="298" stroke-linecap="round" fill="none" d="M13.5,434.5C-5.4,434.5,13.5,-434.5,-13.5,-434.5" id="299" transform="matrix(1,0,0,1,1157,1886)" stroke="#696969" stroke-linejoin="round" ed:parentid="292"/>
    <path ed:tosuperid="300" stroke-linecap="round" fill="none" d="M13.5,54C-5.4,54,13.5,-54,-13.5,-54" id="301" transform="matrix(1,0,0,1,964,1563)" stroke="#696969" stroke-linejoin="round" ed:parentid="294"/>
    <path ed:tosuperid="302" stroke-linecap="round" fill="none" d="M13.5,29.5C-3.4,29.5,8.9,-29.5,-13.5,-29.5" id="303" transform="matrix(1,0,0,1,964,1587)" stroke="#696969" stroke-linejoin="round" ed:parentid="294"/>
    <path ed:tosuperid="304" stroke-linecap="round" fill="none" d="M13.5,-24.5C-2.6,-24.5,7,24.5,-13.5,24.5" id="305" transform="matrix(1,0,0,1,964,1641)" stroke="#696969" stroke-linejoin="round" ed:parentid="294"/>
    <path ed:tosuperid="306" stroke-linecap="round" fill="none" d="M13.5,29.4C-3.4,29.4,8.9,-29.4,-13.5,-29.4" id="307" transform="matrix(1,0,0,1,1112,109)" stroke="#696969" stroke-linejoin="round" ed:parentid="278"/>
    <path ed:tosuperid="308" stroke-linecap="round" fill="none" d="M13.5,-1.1C2.7,-1.1,-5.4,1.1,-13.5,1.1" id="309" transform="matrix(1,0,0,1,1112,140)" stroke="#696969" stroke-linejoin="round" ed:parentid="278"/>
    <path ed:tosuperid="310" stroke-linecap="round" fill="none" d="M13.5,124.1C-5.4,124.1,13.5,-124.1,-13.5,-124.1" id="311" transform="matrix(1,0,0,1,911,386)" stroke="#696969" stroke-linejoin="round" ed:parentid="280"/>
    <path ed:tosuperid="312" stroke-linecap="round" fill="none" d="M-3.7,127.3L-3.7,-127.3L-13.5,-127.3" id="313" transform="matrix(1,0,0,1,1343,1489)" stroke="#696969" stroke-linejoin="round" ed:parentid="107"/>
    <path ed:tosuperid="314" stroke-linecap="round" fill="none" d="M13.5,20.3C-1.8,20.3,5.1,-20.3,-13.5,-20.3" id="315" transform="matrix(1,0,0,1,1142,1341)" stroke="#696969" stroke-linejoin="round" ed:parentid="312"/>
    <path ed:tosuperid="316" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="317" transform="matrix(1,0,0,1,1142,1355)" stroke="#696969" stroke-linejoin="round" ed:parentid="312"/>
    <path ed:tosuperid="318" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="319" transform="matrix(1,0,0,1,1142,1368)" stroke="#696969" stroke-linejoin="round" ed:parentid="312"/>
    <path ed:tosuperid="320" stroke-linecap="round" fill="none" d="M13.5,-20.3C-1.8,-20.3,5.1,20.3,-13.5,20.3" id="321" transform="matrix(1,0,0,1,1142,1382)" stroke="#696969" stroke-linejoin="round" ed:parentid="312"/>
    <path ed:tosuperid="322" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="323" transform="matrix(1,0,0,1,1049,1321)" stroke="#696969" stroke-linejoin="round" ed:parentid="314"/>
    <path ed:tosuperid="324" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="325" transform="matrix(1,0,0,1,1049,1348)" stroke="#696969" stroke-linejoin="round" ed:parentid="316"/>
    <path ed:tosuperid="326" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="327" transform="matrix(1,0,0,1,1037,1375)" stroke="#696969" stroke-linejoin="round" ed:parentid="318"/>
    <path ed:tosuperid="328" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="329" transform="matrix(1,0,0,1,1037,1402)" stroke="#696969" stroke-linejoin="round" ed:parentid="320"/>
    <path ed:tosuperid="330" stroke-linecap="round" fill="none" d="M13.5,11C0.2,11,0.5,-11,-13.5,-11" id="331" transform="matrix(1,0,0,1,948,1440)" stroke="#696969" stroke-linejoin="round" ed:parentid="298"/>
    <path ed:tosuperid="332" stroke-linecap="round" fill="none" d="M13.5,-11C0.2,-11,0.5,11,-13.5,11" id="333" transform="matrix(1,0,0,1,948,1462)" stroke="#696969" stroke-linejoin="round" ed:parentid="298"/>
    <path ed:tosuperid="334" stroke-linecap="round" fill="none" d="M13.5,-4.3C1.7,-4.3,-3.1,4.3,-13.5,4.3" id="335" transform="matrix(1,0,0,1,871,1513)" stroke="#696969" stroke-linejoin="round" ed:parentid="300"/>
    <path ed:tosuperid="336" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="337" transform="matrix(1,0,0,1,871,1551)" stroke="#696969" stroke-linejoin="round" ed:parentid="302"/>
    <path ed:tosuperid="338" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="339" transform="matrix(1,0,0,1,871,1564)" stroke="#696969" stroke-linejoin="round" ed:parentid="302"/>
    <path ed:tosuperid="340" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="341" transform="matrix(1,0,0,1,769,1571)" stroke="#696969" stroke-linejoin="round" ed:parentid="338"/>
    <path ed:tosuperid="342" stroke-linecap="round" fill="none" d="M13.5,27.5C-3.1,27.5,8.2,-27.5,-13.5,-27.5" id="343" transform="matrix(1,0,0,1,823,1638)" stroke="#696969" stroke-linejoin="round" ed:parentid="304"/>
    <path ed:tosuperid="344" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="345" transform="matrix(1,0,0,1,744,1604)" stroke="#696969" stroke-linejoin="round" ed:parentid="342"/>
    <path ed:tosuperid="346" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="347" transform="matrix(1,0,0,1,599,1598)" stroke="#696969" stroke-linejoin="round" ed:parentid="344"/>
    <path ed:tosuperid="348" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="349" transform="matrix(1,0,0,1,744,1617)" stroke="#696969" stroke-linejoin="round" ed:parentid="342"/>
    <path ed:tosuperid="350" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="351" transform="matrix(1,0,0,1,598,1625)" stroke="#696969" stroke-linejoin="round" ed:parentid="348"/>
    <path ed:tosuperid="352" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="353" transform="matrix(1,0,0,1,823,1666)" stroke="#696969" stroke-linejoin="round" ed:parentid="304"/>
    <path ed:tosuperid="354" stroke-linecap="round" fill="none" d="M13.5,7.3C1,7.3,-1.4,-7.3,-13.5,-7.3" id="355" transform="matrix(1,0,0,1,694,1658)" stroke="#696969" stroke-linejoin="round" ed:parentid="352"/>
    <path ed:tosuperid="356" stroke-linecap="round" fill="none" d="M13.5,-6.3C1.2,-6.3,-2,6.3,-13.5,6.3" id="357" transform="matrix(1,0,0,1,694,1672)" stroke="#696969" stroke-linejoin="round" ed:parentid="352"/>
    <path ed:tosuperid="358" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="359" transform="matrix(1,0,0,1,563,1652)" stroke="#696969" stroke-linejoin="round" ed:parentid="354"/>
    <path ed:tosuperid="360" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="361" transform="matrix(1,0,0,1,563,1679)" stroke="#696969" stroke-linejoin="round" ed:parentid="356"/>
    <path ed:tosuperid="362" stroke-linecap="round" fill="none" d="M13.5,-19.8C-1.7,-19.8,4.9,19.8,-13.5,19.8" id="363" transform="matrix(1,0,0,1,823,1685)" stroke="#696969" stroke-linejoin="round" ed:parentid="304"/>
    <path ed:tosuperid="364" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="365" transform="matrix(1,0,0,1,606,1706)" stroke="#696969" stroke-linejoin="round" ed:parentid="362"/>
    <path ed:tosuperid="366" stroke-linecap="round" fill="none" d="M13.5,-33.3C-4,-33.3,10.2,33.3,-13.5,33.3" id="367" transform="matrix(1,0,0,1,823,1699)" stroke="#696969" stroke-linejoin="round" ed:parentid="304"/>
    <path ed:tosuperid="368" stroke-linecap="round" fill="none" d="M13.5,-0.5C2.7,-0.5,-5.4,0.5,-13.5,0.5" id="369" transform="matrix(1,0,0,1,567,1733)" stroke="#696969" stroke-linejoin="round" ed:parentid="366"/>
    <path ed:tosuperid="371" stroke-linecap="round" fill="none" d="M13.5,-1.1C2.7,-1.1,-5.4,1.1,-13.5,1.1" id="372" transform="matrix(1,0,0,1,911,511)" stroke="#696969" stroke-linejoin="round" ed:parentid="280"/>
    <path ed:tosuperid="375" stroke-linecap="round" fill="none" d="M13.5,5.6C1.4,5.6,-2.3,-5.6,-13.5,-5.6" id="376" transform="matrix(1,0,0,1,859,1034)" stroke="#000000" stroke-linejoin="round" ed:parentid="282"/>
    <path ed:tosuperid="378" stroke-linecap="round" fill="none" d="M13.5,368.3C-5.4,368.3,13.5,-368.3,-13.5,-368.3" id="379" transform="matrix(1,0,0,1,948,2117)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="380" stroke-linecap="round" fill="none" d="M13.5,344.3C-5.4,344.3,13.5,-344.3,-13.5,-344.3" id="381" transform="matrix(1,0,0,1,948,2141)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="382" stroke-linecap="round" fill="none" d="M13.5,267.3C-5.4,267.3,13.5,-267.3,-13.5,-267.3" id="383" transform="matrix(1,0,0,1,948,2218)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="384" stroke-linecap="round" fill="none" d="M13.5,171.5C-5.4,171.5,13.5,-171.5,-13.5,-171.5" id="385" transform="matrix(1,0,0,1,948,2314)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="386" stroke-linecap="round" fill="none" d="M13.5,72.5C-5.4,72.5,13.5,-72.5,-13.5,-72.5" id="387" transform="matrix(1,0,0,1,948,2413)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="388" stroke-linecap="round" fill="none" d="M13.5,-145.8C-5.4,-145.8,13.5,145.8,-13.5,145.8" id="389" transform="matrix(1,0,0,1,948,2631)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="390" stroke-linecap="round" fill="none" d="M13.5,-322.8C-5.4,-322.8,13.5,322.8,-13.5,322.8" id="391" transform="matrix(1,0,0,1,948,2808)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="392" stroke-linecap="round" fill="none" d="M13.5,-354.3C-5.4,-354.3,13.5,354.3,-13.5,354.3" id="393" transform="matrix(1,0,0,1,948,2840)" stroke="#696969" stroke-linejoin="round" ed:parentid="296"/>
    <path ed:tosuperid="395" stroke-linecap="round" fill="none" d="M-13.5,172.3L3.7,172.3L3.7,-172.3L13.5,-172.3" id="396" transform="matrix(1,0,0,1,2027,3013)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="397" stroke-linecap="round" fill="none" d="M3.7,-193.5L3.7,193.5L13.5,193.5" id="398" transform="matrix(1,0,0,1,2027,3379)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="399" stroke-linecap="round" fill="none" d="M-13.5,42.3C4.9,42.3,-12.4,-42.3,13.5,-42.3" id="400" transform="matrix(1,0,0,1,2204,2799)" stroke="#696969" stroke-linejoin="round" ed:parentid="395"/>
    <path ed:tosuperid="401" stroke-linecap="round" fill="none" d="M-13.5,-11C-0.2,-11,-0.5,11,13.5,11" id="402" transform="matrix(1,0,0,1,2204,2852)" stroke="#696969" stroke-linejoin="round" ed:parentid="395"/>
    <path ed:tosuperid="403" stroke-linecap="round" fill="none" d="M-13.5,31.3C3.7,31.3,-9.5,-31.3,13.5,-31.3" id="404" transform="matrix(1,0,0,1,2497,2832)" stroke="#696969" stroke-linejoin="round" ed:parentid="401"/>
    <path ed:tosuperid="405" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="406" transform="matrix(1,0,0,1,3063,2800)" stroke="#696969" stroke-linejoin="round" ed:parentid="403"/>
    <path ed:tosuperid="407" stroke-linecap="round" fill="none" d="M-13.5,-6.8C-1.1,-6.8,1.7,6.8,13.5,6.8" id="408" transform="matrix(1,0,0,1,2497,2870)" stroke="#696969" stroke-linejoin="round" ed:parentid="401"/>
    <path ed:tosuperid="411" stroke-linecap="round" fill="none" d="M-13.5,16C0.9,16,-3.1,-16,13.5,-16" id="412" transform="matrix(1,0,0,1,2850,2860)" stroke="#696969" stroke-linejoin="round" ed:parentid="407"/>
    <path ed:tosuperid="413" stroke-linecap="round" fill="none" d="M-13.5,2.5C-2.1,2.5,4,-2.5,13.5,-2.5" id="414" transform="matrix(1,0,0,1,2850,2874)" stroke="#696969" stroke-linejoin="round" ed:parentid="407"/>
    <path ed:tosuperid="415" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="416" transform="matrix(1,0,0,1,3075,2871)" stroke="#696969" stroke-linejoin="round" ed:parentid="413"/>
    <path ed:tosuperid="417" stroke-linecap="round" fill="none" d="M-13.5,-11C-0.2,-11,-0.5,11,13.5,11" id="418" transform="matrix(1,0,0,1,2850,2887)" stroke="#696969" stroke-linejoin="round" ed:parentid="407"/>
    <path ed:tosuperid="419" stroke-linecap="round" fill="none" d="M-13.5,0C-2.7,0,5.4,0,13.5,0" id="420" transform="matrix(1,0,0,1,3075,2898)" stroke="#696969" stroke-linejoin="round" ed:parentid="417"/>
    <path ed:tosuperid="421" stroke-linecap="round" fill="none" d="M-13.5,-24.5C2.6,-24.5,-7,24.5,13.5,24.5" id="422" transform="matrix(1,0,0,1,2850,2901)" stroke="#696969" stroke-linejoin="round" ed:parentid="407"/>
    <path ed:tosuperid="423" stroke-linecap="round" fill="none" d="M3.7,-16.1L3.7,16.1L13.5,16.1" id="424" transform="matrix(1,0,0,1,2027,3202)" stroke="#696969" stroke-linejoin="round" ed:parentid="109"/>
    <path ed:tosuperid="425" stroke-linecap="round" fill="none" d="M-13.5,132.6C5.4,132.6,-13.5,-132.6,13.5,-132.6" id="426" transform="matrix(1,0,0,1,2240,3085)" stroke="#696969" stroke-linejoin="round" ed:parentid="423"/>
    <path ed:tosuperid="427" stroke-linecap="round" fill="none" d="M-13.5,119.1C5.4,119.1,-13.5,-119.1,13.5,-119.1" id="428" transform="matrix(1,0,0,1,2240,3099)" stroke="#696969" stroke-linejoin="round" ed:parentid="423"/>
    <path ed:tosuperid="429" stroke-linecap="round" fill="none" d="M-13.5,105.6C5.4,105.6,-13.5,-105.6,13.5,-105.6" id="430" transform="matrix(1,0,0,1,2240,3112)" stroke="#696969" stroke-linejoin="round" ed:parentid="423"/>
    <path ed:tosuperid="431" stroke-linecap="round" fill="none" d="M-13.5,92.1C5.4,92.1,-13.5,-92.1,13.5,-92.1" id="432" transform="matrix(1,0,0,1,2240,3126)" stroke="#696969" stroke-linejoin="round" ed:parentid="423"/>
    <path ed:tosuperid="433" stroke-linecap="round" fill="none" d="M-13.5,-21.9C2.1,-21.9,-5.8,21.9,13.5,21.9" id="434" transform="matrix(1,0,0,1,2240,3240)" stroke="#696969" stroke-linejoin="round" ed:parentid="423"/>
    <path ed:tosuperid="435" stroke-linecap="round" fill="none" d="M-13.5,24.5C2.6,24.5,-7,-24.5,13.5,-24.5" id="436" transform="matrix(1,0,0,1,2192,3548)" stroke="#696969" stroke-linejoin="round" ed:parentid="397"/>
    <path ed:tosuperid="437" stroke-linecap="round" fill="none" d="M-13.5,-2.5C-2.1,-2.5,4,2.5,13.5,2.5" id="438" transform="matrix(1,0,0,1,2192,3575)" stroke="#696969" stroke-linejoin="round" ed:parentid="397"/>
    <path ed:tosuperid="439" stroke-linecap="round" fill="none" d="M-13.5,-6.8C-1.1,-6.8,1.7,6.8,13.5,6.8" id="440" transform="matrix(1,0,0,1,2285,3584)" stroke="#696969" stroke-linejoin="round" ed:parentid="437"/>
    <path ed:tosuperid="441" stroke-linecap="round" fill="none" d="M-13.5,6.8C-1.1,6.8,1.7,-6.8,13.5,-6.8" id="442" transform="matrix(1,0,0,1,2285,3571)" stroke="#696969" stroke-linejoin="round" ed:parentid="437"/>
    <path ed:tosuperid="443" stroke-linecap="round" fill="none" d="M-13.5,6.8C-1.1,6.8,1.7,-6.8,13.5,-6.8" id="444" transform="matrix(1,0,0,1,2297,3517)" stroke="#696969" stroke-linejoin="round" ed:parentid="435"/>
    <path ed:tosuperid="445" stroke-linecap="round" fill="none" d="M-13.5,-6.8C-1.1,-6.8,1.7,6.8,13.5,6.8" id="446" transform="matrix(1,0,0,1,2297,3530)" stroke="#696969" stroke-linejoin="round" ed:parentid="435"/>
    <path ed:tosuperid="447" stroke-linecap="round" fill="none" d="M-13.5,-31.3C3.7,-31.3,-9.5,31.3,13.5,31.3" id="448" transform="matrix(1,0,0,1,2192,3604)" stroke="#696969" stroke-linejoin="round" ed:parentid="397"/>
    <path ed:tosuperid="450" stroke-linecap="round" fill="none" d="M13.5,186.6L-3.7,186.6L-3.7,-186.6L-13.5,-186.6" id="451" transform="matrix(1,0,0,1,1343,3487)" stroke="#696969" stroke-linejoin="round" ed:parentid="111"/>
    <path ed:tosuperid="452" stroke-linecap="round" fill="none" d="M-3.7,97.1L-3.7,-97.1L-13.5,-97.1" id="453" transform="matrix(1,0,0,1,1343,3576)" stroke="#696969" stroke-linejoin="round" ed:parentid="111"/>
    <path ed:tosuperid="454" stroke-linecap="round" fill="none" d="M13.5,9.3C0.5,9.3,-0.4,-9.3,-13.5,-9.3" id="455" transform="matrix(1,0,0,1,1178,3291)" stroke="#696969" stroke-linejoin="round" ed:parentid="450"/>
    <path ed:tosuperid="456" stroke-linecap="round" fill="none" d="M13.5,-11C0.2,-11,0.5,11,-13.5,11" id="457" transform="matrix(1,0,0,1,1178,3311)" stroke="#696969" stroke-linejoin="round" ed:parentid="450"/>
    <path ed:tosuperid="458" stroke-linecap="round" fill="none" d="M13.5,6.8C1.1,6.8,-1.7,-6.8,-13.5,-6.8" id="459" transform="matrix(1,0,0,1,967,3315)" stroke="#696969" stroke-linejoin="round" ed:parentid="456"/>
    <path ed:tosuperid="460" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="461" transform="matrix(1,0,0,1,967,3329)" stroke="#696969" stroke-linejoin="round" ed:parentid="456"/>
    <path ed:tosuperid="462" stroke-linecap="round" fill="none" d="M13.5,44.8C-5.1,44.8,12.8,-44.8,-13.5,-44.8" id="463" transform="matrix(1,0,0,1,1094,3434)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="464" stroke-linecap="round" fill="none" d="M13.5,-6.8C1.1,-6.8,-1.7,6.8,-13.5,6.8" id="465" transform="matrix(1,0,0,1,1094,3486)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="466" stroke-linecap="round" fill="none" d="M13.5,13.5C-0.4,13.5,1.8,-13.5,-13.5,-13.5" id="467" transform="matrix(1,0,0,1,1013,3376)" stroke="#696969" stroke-linejoin="round" ed:parentid="462"/>
    <path ed:tosuperid="468" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="469" transform="matrix(1,0,0,1,1013,3390)" stroke="#696969" stroke-linejoin="round" ed:parentid="462"/>
    <path ed:tosuperid="470" stroke-linecap="round" fill="none" d="M13.5,-13.5C-0.4,-13.5,1.8,13.5,-13.5,13.5" id="471" transform="matrix(1,0,0,1,1013,3403)" stroke="#696969" stroke-linejoin="round" ed:parentid="462"/>
    <path ed:tosuperid="472" stroke-linecap="round" fill="none" d="M13.5,2.5C2.1,2.5,-4,-2.5,-13.5,-2.5" id="473" transform="matrix(1,0,0,1,896,3490)" stroke="#696969" stroke-linejoin="round" ed:parentid="474"/>
    <path ed:tosuperid="474" stroke-linecap="round" fill="none" d="M13.5,0C2.7,0,-5.4,0,-13.5,0" id="475" transform="matrix(1,0,0,1,1013,3493)" stroke="#696969" stroke-linejoin="round" ed:parentid="464"/>
    <path ed:tosuperid="476" stroke-linecap="round" fill="none" d="M13.5,-11C0.2,-11,0.5,11,-13.5,11" id="477" transform="matrix(1,0,0,1,896,3504)" stroke="#696969" stroke-linejoin="round" ed:parentid="474"/>
    <path ed:tosuperid="480" stroke-linecap="round" fill="none" d="M13.5,-24.5C-2.6,-24.5,7,24.5,-13.5,24.5" id="481" transform="matrix(1,0,0,1,1013,3517)" stroke="#696969" stroke-linejoin="round" ed:parentid="464"/>
    <path ed:tosuperid="482" stroke-linecap="round" fill="none" d="M13.5,24.5C-2.6,24.5,7,-24.5,-13.5,-24.5" id="483" transform="matrix(1,0,0,1,1013,3468)" stroke="#696969" stroke-linejoin="round" ed:parentid="464"/>
    <path ed:tosuperid="484" stroke-linecap="round" fill="none" d="M13.5,-44.8C-5.1,-44.8,12.8,44.8,-13.5,44.8" id="485" transform="matrix(1,0,0,1,1094,3524)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="486" stroke-linecap="round" fill="none" d="M13.5,-58.3C-5.4,-58.3,13.5,58.3,-13.5,58.3" id="487" transform="matrix(1,0,0,1,1094,3537)" stroke="#696969" stroke-linejoin="round" ed:parentid="452"/>
    <path ed:tosuperid="488" stroke-linecap="round" fill="none" d="M-3.7,-94.6L-3.7,94.6L-13.5,94.6" id="489" transform="matrix(1,0,0,1,1343,3768)" stroke="#696969" stroke-linejoin="round" ed:parentid="111"/>
    <path ed:tosuperid="490" stroke-linecap="round" fill="none" d="M13.5,84.3C-5.4,84.3,13.5,-84.3,-13.5,-84.3" id="491" transform="matrix(1,0,0,1,1250,3778)" stroke="#696969" stroke-linejoin="round" ed:parentid="488"/>
    <path ed:tosuperid="492" stroke-linecap="round" fill="none" d="M13.5,-42.5C-5,-42.5,12.5,42.5,-13.5,42.5" id="493" transform="matrix(1,0,0,1,1250,3905)" stroke="#696969" stroke-linejoin="round" ed:parentid="488"/>
    <path ed:tosuperid="619" stroke-linecap="round" fill="none" d="M0,-19.5L0,19.5" id="620" transform="matrix(1,0,0,1,1656,1218)" stroke="#696969" stroke-linejoin="round" ed:parentid="616"/>
    <path ed:tosuperid="621" stroke-linecap="round" fill="none" d="M0,-19.5L0,19.5" id="622" transform="matrix(1,0,0,1,1656,1276)" stroke="#696969" stroke-linejoin="round" ed:parentid="616"/>
    <path ed:tosuperid="623" stroke-linecap="round" fill="none" d="M0,-19.5L0,19.5" id="624" transform="matrix(1,0,0,1,1656,1351)" stroke="#696969" stroke-linejoin="round" ed:parentid="616"/>
    <path ed:tosuperid="625" stroke-linecap="round" fill="none" d="M0,-19.5L0,19.5" id="626" transform="matrix(1,0,0,1,1656,1426)" stroke="#696969" stroke-linejoin="round" ed:parentid="616"/>
    <g ed:width="101.16" ed:height="31" ed:layout="leftmap" id="373" transform="matrix(1,0,0,1,1162,21)" ed:parentid="278" ed:topictype="callout">
        <path fill="#f9ebef" d="M7.8,0L93.4,0L101.2,15.5L93.4,31L58.1,31L63.7,95L48,31L7.8,31L0,15.5L7.8,0z" stroke="#dd7195" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="20" x="13" style="white-space:pre">面向接口编程</tspan>
        </text>
    </g>
    <g ed:width="218.691" ed:height="31" ed:layout="leftmap" id="374" transform="matrix(1,0,0,1,1003,202)" ed:parentid="280" ed:topictype="callout">
        <path fill="#f9ebef" d="M7.8,0L210.9,0L218.7,15.5L210.9,31L115.2,31L123.7,286L105.2,31L7.8,31L0,15.5L7.8,0z" stroke="#dd7195" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="20" x="13" style="white-space:pre">面向接口编程+抽取相同方法到父类</tspan>
        </text>
    </g>
    <g ed:width="161.16" ed:height="31" ed:layout="rightmap" id="394" transform="matrix(1,0,0,1,1878,2696)" ed:parentid="109" ed:topictype="callout">
        <path fill="#f9ebef" d="M7.8,0L153.4,0L161.2,15.5L153.4,31L85.1,31L66.1,471.8L75.1,31L7.8,31L0,15.5L7.8,0z" stroke="#dd7195" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="20" x="13" style="white-space:pre">封装复杂对象的构造逻辑</tspan>
        </text>
    </g>
    <g ed:width="269.094" ed:height="84" ed:layout="map" id="101" transform="matrix(1,0,0,1,1543,2020)" ed:topictype="mainidea">
        <path fill="#6d7979" d="M4,0L265.1,0C267.8,0,269.1,1.3,269.1,4L269.1,80C269.1,82.7,267.8,84,265.1,84L4,84C1.3,84,0,82.7,0,80L0,4C0,1.3,1.3,0,4,0z" stroke-width="3" stroke="#6d7979" stroke-linejoin="round"/>
        <text class="st2">
            <tspan y="37" x="62" style="white-space:pre">设计模式-创建型</tspan>
            <tspan y="64" x="22" style="white-space:pre">（解决“对象的创建”问题）</tspan>
        </text>
    </g>
    <g ed:width="123.484" ed:height="35" ed:layout="rightmap" id="102" transform="matrix(1,0,0,1,1875,1558)" ed:parentid="101">
        <path fill="#ffc000" d="M4,0L119.5,0C122.2,0,123.5,1.3,123.5,4L123.5,31C123.5,33.7,122.2,35,119.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#fcece8" stroke-linejoin="round"/>
        <text class="st3">
            <tspan y="24" x="18" style="white-space:pre">1、单例模式</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="104" transform="matrix(1,0,0,1,2025,529)" ed:parentid="102">
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">为什么要使用单例？</tspan>
        </text>
    </g>
    <g ed:width="123.484" ed:height="35" ed:layout="leftmap" id="107" transform="matrix(1,0,0,1,1356,1599)" ed:parentid="101">
        <path fill="#ffc000" d="M4,0L119.5,0C122.2,0,123.5,1.3,123.5,4L123.5,31C123.5,33.7,122.2,35,119.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#fcece8" stroke-linejoin="round"/>
        <text class="st3">
            <tspan y="24" x="18" style="white-space:pre">2、工厂模式</tspan>
        </text>
    </g>
    <g ed:width="138.484" ed:height="35" ed:layout="rightmap" id="109" transform="matrix(1,0,0,1,1875,3168)" ed:parentid="101">
        <path fill="#ffc000" d="M4,0L134.5,0C137.2,0,138.5,1.3,138.5,4L138.5,31C138.5,33.7,137.2,35,134.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#fcece8" stroke-linejoin="round"/>
        <text class="st3">
            <tspan y="24" x="18" style="white-space:pre">3、构造器模式</tspan>
        </text>
    </g>
    <g ed:width="123.484" ed:height="35" ed:layout="leftmap" id="111" transform="matrix(1,0,0,1,1356,3656)" ed:parentid="101">
        <path fill="#ffc000" d="M4,0L119.5,0C122.2,0,123.5,1.3,123.5,4L123.5,31C123.5,33.7,122.2,35,119.5,35L4,35C1.3,35,0,33.7,0,31L0,4C0,1.3,1.3,0,4,0z" stroke="#fcece8" stroke-linejoin="round"/>
        <text class="st3">
            <tspan y="24" x="18" style="white-space:pre">4、原型模式</tspan>
        </text>
    </g>
    <g ed:width="162" ed:height="20.5" ed:layout="rightmap" id="151" transform="matrix(1,0,0,1,2025,489)" ed:parentid="102">
        <path fill="none" d="M0,20.5L162,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">一个类只允许创建一个对象</tspan>
        </text>
    </g>
    <g ed:width="114" ed:height="20.5" ed:layout="rightmap" id="153" transform="matrix(1,0,0,1,2178,516)" ed:parentid="104">
        <path fill="none" d="M0,20.5L114,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">处理资源访问冲突</tspan>
        </text>
    </g>
    <g ed:width="102" ed:height="20.5" ed:layout="rightmap" id="155" transform="matrix(1,0,0,1,2178,543)" ed:parentid="104">
        <path fill="none" d="M0,20.5L102,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">表示全局唯一类</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="157" transform="matrix(1,0,0,1,2025,962)" ed:parentid="102">
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">如何实现一个单例？</tspan>
        </text>
    </g>
    <g ed:width="333.25" ed:height="20.5" ed:layout="rightmap" id="159" transform="matrix(1,0,0,1,2271,570)" ed:parentid="167">
        <path fill="none" d="M0,20.5L333.3,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">构造函数需要private访问权限，避免外部通过new创建实例</tspan>
        </text>
    </g>
    <g ed:width="186" ed:height="20.5" ed:layout="rightmap" id="161" transform="matrix(1,0,0,1,2271,597)" ed:parentid="167">
        <path fill="none" d="M0,20.5L186,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">考虑对象创建时的线程安全问题</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="rightmap" id="163" transform="matrix(1,0,0,1,2271,624)" ed:parentid="167">
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">考虑是否支持延迟加载</tspan>
        </text>
    </g>
    <g ed:width="248.766" ed:height="20.5" ed:layout="rightmap" id="165" transform="matrix(1,0,0,1,2271,651)" ed:parentid="167">
        <path fill="none" d="M0,20.5L248.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">考虑getInstance()性能是否高（是否枷锁）</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="rightmap" id="167" transform="matrix(1,0,0,1,2178,610)" ed:parentid="157">
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">关注的点</tspan>
        </text>
    </g>
    <g ed:width="73" ed:height="22.5" ed:layout="rightmap" id="169" transform="matrix(1,0,0,1,2178,746)" ed:parentid="157">
        <path fill="none" d="M0,22.5L73,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">饿汉式</tspan>
        </text>
    </g>
    <symbol id="flag1">
        <image xlink:href="" width="16" height="16"/>
    </symbol>
    <g ed:width="354.359" ed:height="20.5" ed:layout="rightmap" id="171" transform="matrix(1,0,0,1,2278,763)" ed:parentid="169">
        <path fill="none" d="M0,20.5L354.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">在类加载的时候，Instance静态实例就已经创建并初始化好了。</tspan>
        </text>
    </g>
    <g ed:width="102" ed:height="20.5" ed:layout="rightmap" id="173" transform="matrix(1,0,0,1,2278,790)" ed:parentid="169">
        <path fill="none" d="M0,20.5L102,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">不支持延时加载</tspan>
        </text>
    </g>
    <g ed:width="73" ed:height="22.5" ed:layout="rightmap" id="175" transform="matrix(1,0,0,1,2178,922)" ed:parentid="157">
        <path fill="none" d="M0,22.5L73,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">懒汉式</tspan>
        </text>
    </g>
    <g ed:width="222.375" ed:height="20.5" ed:layout="rightmap" id="177" transform="matrix(1,0,0,1,2278,817)" ed:parentid="169">
        <path fill="none" d="M0,20.5L222.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">instance实例创建的过程是线程安全的</tspan>
        </text>
    </g>
    <g ed:width="374.359" ed:height="79" ed:layout="rightmap" id="179" transform="matrix(1,0,0,1,2278,678)" ed:parentid="169">
        <path fill="#ebebeb" d="M0,0L374.4,0L374.4,79L0,79L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" class="st4" style="white-space:pre">private static final IdGenerator instance = new IdGenerator();</tspan>
            <tspan y="28" x="9" style="white-space:pre">private IdGenerator() {}</tspan>
            <tspan y="43" x="9" style="white-space:pre">public static IdGenerator getInstance() {</tspan>
            <tspan y="58" x="9" style="white-space:pre">    return instance;</tspan>
            <tspan y="73" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="90" ed:height="20.5" ed:layout="rightmap" id="181" transform="matrix(1,0,0,1,2278,975)" ed:parentid="175">
        <path fill="none" d="M0,20.5L90,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">支持延时加载</tspan>
        </text>
    </g>
    <g ed:width="331.953" ed:height="124" ed:layout="rightmap" id="183" transform="matrix(1,0,0,1,2278,844)" ed:parentid="175">
        <path fill="#ebebeb" d="M0,0L332,0L332,124L0,124L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">private static IdGenerator instance;</tspan>
            <tspan y="28" x="9" style="white-space:pre">private IdGenerator() {}</tspan>
            <tspan y="43" x="9" style="white-space:pre">public static </tspan>
            <tspan class="st4" style="white-space:pre">synchronized</tspan>
            <tspan style="white-space:pre"> IdGenerator getInstance() {</tspan>
            <tspan y="58" x="9" style="white-space:pre">    if (instance == null) {</tspan>
            <tspan y="73" x="9" style="white-space:pre">        instance = new IdGenerator();</tspan>
            <tspan y="88" x="9" style="white-space:pre">    }</tspan>
            <tspan y="103" x="9" style="white-space:pre">    return instance;</tspan>
            <tspan y="118" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="358.953" ed:height="20.5" ed:layout="rightmap" id="185" transform="matrix(1,0,0,1,2278,1002)" ed:parentid="175">
        <path fill="none" d="M0,20.5L359,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">getInstance()加了一把大锁（synchronzed），导致并发度很低</tspan>
        </text>
    </g>
    <g ed:width="85" ed:height="22.5" ed:layout="rightmap" id="187" transform="matrix(1,0,0,1,2178,1118)" ed:parentid="157">
        <path fill="none" d="M0,22.5L85,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">双重监测</tspan>
        </text>
    </g>
    <g ed:width="258.5" ed:height="201" ed:layout="rightmap" id="189" transform="matrix(1,0,0,1,2290,1029)" ed:parentid="187">
        <path fill="#ebebeb" d="M0,0L258.5,0L258.5,201L0,201L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">private static IdGenerator instance; </tspan>
            <tspan y="28" x="9" style="white-space:pre">private IdGenerator() {} </tspan>
            <tspan y="43" x="9" style="white-space:pre">public static IdGenerator getInstance() { </tspan>
            <tspan y="58" x="9" style="white-space:pre">    </tspan>
            <tspan class="st4" style="white-space:pre">if (instance == null) </tspan>
            <tspan style="white-space:pre">{ </tspan>
            <tspan y="73" x="9" style="white-space:pre">        </tspan>
            <tspan class="st4" style="white-space:pre">synchronized(IdGenerator.class)</tspan>
            <tspan style="white-space:pre"> { </tspan>
            <tspan y="90" x="9" style="white-space:pre">            // 此处为类级别的锁</tspan>
            <tspan y="105" x="9" style="white-space:pre">            </tspan>
            <tspan class="st4" style="white-space:pre">if (instance == null)</tspan>
            <tspan style="white-space:pre"> {</tspan>
            <tspan y="120" x="9" style="white-space:pre">                instance = new IdGenerator(); </tspan>
            <tspan y="135" x="9" style="white-space:pre">            } </tspan>
            <tspan y="150" x="9" style="white-space:pre">        }</tspan>
            <tspan y="165" x="9" style="white-space:pre">    }</tspan>
            <tspan y="180" x="9" style="white-space:pre">    return instance; </tspan>
            <tspan y="195" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="97" ed:height="22.5" ed:layout="rightmap" id="191" transform="matrix(1,0,0,1,2178,1294)" ed:parentid="157">
        <path fill="none" d="M0,22.5L97,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">静态内部类</tspan>
        </text>
    </g>
    <g ed:width="408.531" ed:height="139" ed:layout="rightmap" id="193" transform="matrix(1,0,0,1,2302,1236)" ed:parentid="191">
        <path fill="#ebebeb" d="M0,0L408.5,0L408.5,139L0,139L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class IdGenerator {</tspan>
            <tspan y="28" x="9" style="white-space:pre">    private IdGenerator() {}</tspan>
            <tspan y="43" x="9" style="white-space:pre">    </tspan>
            <tspan class="st4" style="white-space:pre">private static class SingletonHolder{ </tspan>
            <tspan y="58" x="9" class="st4" style="white-space:pre">        private static final IdGenerator instance = new IdGenerator(); </tspan>
            <tspan y="73" x="9" class="st4" style="white-space:pre">    }</tspan>
            <tspan y="88" x="9" style="white-space:pre">    public static IdGenerator getInstance() { </tspan>
            <tspan y="103" x="9" style="white-space:pre">        return SingletonHolder.instance; </tspan>
            <tspan y="118" x="9" style="white-space:pre">    }</tspan>
            <tspan y="133" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="119.063" ed:height="20.5" ed:layout="rightmap" id="195" transform="matrix(1,0,0,1,2025,1573)" ed:parentid="102">
        <path fill="none" d="M0,20.5L119.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">单例存在哪些问题?</tspan>
        </text>
    </g>
    <g ed:width="198.016" ed:height="20.5" ed:layout="rightmap" id="197" transform="matrix(1,0,0,1,2171,1426)" ed:parentid="195">
        <path fill="none" d="M0,20.5L198,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">1. 单例对 OOP 特性的支持不友好</tspan>
        </text>
    </g>
    <g ed:width="222" ed:height="20.5" ed:layout="rightmap" id="199" transform="matrix(1,0,0,1,2396,1382)" ed:parentid="197">
        <path fill="none" d="M0,20.5L222,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">违背了基于接口而非实现的设计原则，</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="201" transform="matrix(1,0,0,1,2396,1409)" ed:parentid="197">
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">如果未来某一天，希望针对不同的业务采用不同的 ID 生成算法，订单 ID 和用户 ID。需要修</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">改所有用到IdGenerator类的代码</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="203" transform="matrix(1,0,0,1,2396,1453)" ed:parentid="197">
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">一旦你选择将某个类设计成到单例类，也就意味着放弃了继承和多态这两个强有力的面向对象</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">特性，也就相当于损失了可以应对未来需求变化的扩展性</tspan>
        </text>
    </g>
    <g ed:width="189.172" ed:height="20.5" ed:layout="rightmap" id="205" transform="matrix(1,0,0,1,2171,1505)" ed:parentid="195">
        <path fill="none" d="M0,20.5L189.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">2. 单例会隐藏类之间的依赖关系</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="207" transform="matrix(1,0,0,1,2388,1497)" ed:parentid="205">
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">单例类不需要显示创建、不需要依赖参数传递，在函数中直接调用就可以了。这种调用关系就</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">会非常隐蔽。</tspan>
        </text>
    </g>
    <g ed:width="177.172" ed:height="20.5" ed:layout="rightmap" id="209" transform="matrix(1,0,0,1,2171,1554)" ed:parentid="195">
        <path fill="none" d="M0,20.5L177.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">3. 单例对代码的扩展性不友好</tspan>
        </text>
    </g>
    <g ed:width="581.5" ed:height="20.5" ed:layout="rightmap" id="211" transform="matrix(1,0,0,1,2376,1541)" ed:parentid="209">
        <path fill="none" d="M0,20.5L581.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">在系统中创建两个数据库连接池，慢 SQL 独享一个数据库连接池，其他 SQL 独享另外一个数据库连接池。</tspan>
        </text>
    </g>
    <g ed:width="294" ed:height="20.5" ed:layout="rightmap" id="213" transform="matrix(1,0,0,1,2376,1568)" ed:parentid="209">
        <path fill="none" d="M0,20.5L294,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">单例类在某些情况下会影响代码的扩展性、灵活性。</tspan>
        </text>
    </g>
    <g ed:width="189.172" ed:height="20.5" ed:layout="rightmap" id="215" transform="matrix(1,0,0,1,2171,1625)" ed:parentid="195">
        <path fill="none" d="M0,20.5L189.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">4. 单例对代码的可测试性不友好</tspan>
        </text>
    </g>
    <g ed:width="357.297" ed:height="20.5" ed:layout="rightmap" id="217" transform="matrix(1,0,0,1,2387,1595)" ed:parentid="215">
        <path fill="none" d="M0,20.5L357.3,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">如果单例类依赖比较重的外部资源，导致无法实现 mock 替换。</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="54.5" ed:layout="rightmap" id="219" transform="matrix(1,0,0,1,2388,1622)" ed:parentid="215">
        <path fill="none" d="M0,54.5L514,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">如果单例类持有成员变量，它实际上相当于一种全局变量，被所有的代码共享。如果它的成员</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">变量是可以被修改的，那在编写单元测试的时候，还需要注意不同测试用例之间，修改了单例</tspan>
            <tspan y="48.6" x="8" style="white-space:pre">类中的同一个成员变量的值，从而导致测试结果互相影响的问题。</tspan>
        </text>
    </g>
    <g ed:width="189.172" ed:height="20.5" ed:layout="rightmap" id="221" transform="matrix(1,0,0,1,2171,1723)" ed:parentid="195">
        <path fill="none" d="M0,20.5L189.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">5. 单例不支持有参数的构造函数</tspan>
        </text>
    </g>
    <g ed:width="378" ed:height="20.5" ed:layout="rightmap" id="223" transform="matrix(1,0,0,1,2388,1683)" ed:parentid="221">
        <path fill="none" d="M0,20.5L378,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">比如创建一个连接池的单例对象，没法通过参数来指定连接池的大小</tspan>
        </text>
    </g>
    <g ed:width="121.578" ed:height="20.5" ed:layout="rightmap" id="225" transform="matrix(1,0,0,1,2388,1737)" ed:parentid="221">
        <path fill="none" d="M0,20.5L121.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">解决方案（推荐3）</tspan>
        </text>
    </g>
    <g ed:width="283.406" ed:height="20.5" ed:layout="rightmap" id="227" transform="matrix(1,0,0,1,2536,1710)" ed:parentid="225">
        <path fill="none" d="M0,20.5L283.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">1. 创建完实例之后，再调用 init() 函数传递参数。</tspan>
        </text>
    </g>
    <g ed:width="205.422" ed:height="20.5" ed:layout="rightmap" id="229" transform="matrix(1,0,0,1,2536,1737)" ed:parentid="225">
        <path fill="none" d="M0,20.5L205.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">2. 将参数放到 getIntance() 方法中</tspan>
        </text>
    </g>
    <g ed:width="296.141" ed:height="20.5" ed:layout="rightmap" id="231" transform="matrix(1,0,0,1,2769,1737)" ed:parentid="229">
        <path fill="none" d="M0,20.5L296.1,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">如果两次执行getInstance(),第2次的参数没有起作用</tspan>
        </text>
    </g>
    <g ed:width="213.172" ed:height="20.5" ed:layout="rightmap" id="233" transform="matrix(1,0,0,1,2536,1764)" ed:parentid="225">
        <path fill="none" d="M0,20.5L213.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">3. 将参数放到另外一个全局变量中。</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="236" transform="matrix(1,0,0,1,2025,1818)" ed:parentid="102">
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">有何替代解决方案？</tspan>
        </text>
    </g>
    <g ed:width="114" ed:height="20.5" ed:layout="rightmap" id="240" transform="matrix(1,0,0,1,2178,1791)" ed:parentid="236">
        <path fill="none" d="M0,20.5L114,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">用静态方法来实现</tspan>
        </text>
    </g>
    <g ed:width="174" ed:height="20.5" ed:layout="rightmap" id="242" transform="matrix(1,0,0,1,2319,1791)" ed:parentid="240">
        <path fill="none" d="M0,20.5L174,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">但并不能解决之前提到的问题</tspan>
        </text>
    </g>
    <g ed:width="328.594" ed:height="20.5" ed:layout="rightmap" id="244" transform="matrix(1,0,0,1,2178,1818)" ed:parentid="236">
        <path fill="none" d="M0,20.5L328.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">通过工厂模式、IOC 容器（比如 Spring IOC 容器）来保证</tspan>
        </text>
    </g>
    <g ed:width="450" ed:height="20.5" ed:layout="rightmap" id="246" transform="matrix(1,0,0,1,2178,1845)" ed:parentid="236">
        <path fill="none" d="M0,20.5L450,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">通过程序员自己来保证（自己在编写代码的时候自己保证不要创建两个类对象）。</tspan>
        </text>
    </g>
    <g ed:width="186" ed:height="20.5" ed:layout="rightmap" id="248" transform="matrix(1,0,0,1,2025,2009)" ed:parentid="102">
        <path fill="none" d="M0,20.5L186,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">如何理解单例模式中的唯一性？</tspan>
        </text>
    </g>
    <g ed:width="210" ed:height="20.5" ed:layout="rightmap" id="250" transform="matrix(1,0,0,1,2343,2014)" ed:parentid="252">
        <path fill="none" d="M0,20.5L210,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">单例模式创建的对象是进程唯一的。</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="rightmap" id="252" transform="matrix(1,0,0,1,2238,2014)" ed:parentid="248">
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">进程内唯一</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="rightmap" id="254" transform="matrix(1,0,0,1,2238,1929)" ed:parentid="248">
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">线程内唯一</tspan>
        </text>
    </g>
    <g ed:width="387.313" ed:height="20.5" ed:layout="rightmap" id="256" transform="matrix(1,0,0,1,2343,1872)" ed:parentid="254">
        <path fill="none" d="M0,20.5L387.3,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">Java 提供了 ThreadLocal 工具类，可以更加轻松地实现线程唯一单例</tspan>
        </text>
    </g>
    <g ed:width="126" ed:height="20.5" ed:layout="rightmap" id="258" transform="matrix(1,0,0,1,2238,2094)" ed:parentid="248">
        <path fill="none" d="M0,20.5L126,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">多进程唯一（集群）</tspan>
        </text>
    </g>
    <g ed:width="354" ed:height="20.5" ed:layout="rightmap" id="260" transform="matrix(1,0,0,1,2391,2041)" ed:parentid="258">
        <path fill="none" d="M0,20.5L354,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">不同的进程间共享同一个对象，不能创建同一个类的多个对象。</tspan>
        </text>
    </g>
    <g ed:width="616.563" ed:height="109" ed:layout="rightmap" id="262" transform="matrix(1,0,0,1,2343,1899)" ed:parentid="254">
        <path fill="#ebebeb" d="M0,0L616.6,0L616.6,109L0,109L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">private static final </tspan>
            <tspan class="st4" style="white-space:pre">ConcurrentHashMap&lt;Long, IdGenerator></tspan>
            <tspan style="white-space:pre"> instances = new ConcurrntHashMap&lt;>();</tspan>
            <tspan y="43" x="9" style="white-space:pre">public static IdGenerator getInstance() { </tspan>
            <tspan y="58" x="9" style="white-space:pre">    Long currentThreadId = Thread.currentThread().getId(); </tspan>
            <tspan y="73" x="9" style="white-space:pre">    instances.putIfAbsent(currentThreadId, new IdGenerator()); </tspan>
            <tspan y="88" x="9" style="white-space:pre">    return instances.get(currentThreadId); </tspan>
            <tspan y="103" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="600.016" ed:height="37.5" ed:layout="rightmap" id="264" transform="matrix(1,0,0,1,2391,2068)" ed:parentid="258">
        <path fill="none" d="M0,37.5L600,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">需要把这个单例对象</tspan>
            <tspan class="st4" style="white-space:pre">序列化</tspan>
            <tspan style="white-space:pre">并存储到外部共享存储区（文件）。进程在使用时，需要先从外部共享存储区中将</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">它读取到内存，并反序列化成对象，然后再使用，使用完成之后还需要再存储回外部共享存储区。</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="54.5" ed:layout="rightmap" id="266" transform="matrix(1,0,0,1,2391,2112)" ed:parentid="258">
        <path fill="none" d="M0,54.5L514,54.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">为了保证任何时刻，在进程间都只有一份对象存在，</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">一个进程在获取到对象之后，需要对对象加锁，避免其他进程再将其获取。在进程使用完这个</tspan>
            <tspan y="48.6" x="8" style="white-space:pre">对象之后，还需要显式地将对象从内存中删除，并且释放对对象的加锁。</tspan>
        </text>
    </g>
    <g ed:width="169" ed:height="22.5" ed:layout="rightmap" id="268" transform="matrix(1,0,0,1,2025,2407)" ed:parentid="102">
        <path fill="none" d="M0,22.5L169,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#star1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">如何实现一个多例模式？</tspan>
        </text>
    </g>
    <symbol id="star1">
        <image xlink:href="" width="16" height="16"/>
    </symbol>
    <g ed:width="510.703" ed:height="20.5" ed:layout="rightmap" id="270" transform="matrix(1,0,0,1,2221,2173)" ed:parentid="268">
        <path fill="none" d="M0,20.5L510.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">“多例”指的就是，一个类可以创建多个对象，但是个数是有限制的，比如只能创建 3 个对象。</tspan>
        </text>
    </g>
    <g ed:width="514.938" ed:height="409" ed:layout="rightmap" id="272" transform="matrix(1,0,0,1,2221,2200)" ed:parentid="268">
        <path fill="#ebebeb" d="M0,0L514.9,0L514.9,409L0,409L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class BackendServer { </tspan>
            <tspan y="28" x="9" style="white-space:pre">private long serverNo; </tspan>
            <tspan y="43" x="9" style="white-space:pre">private String serverAddress; </tspan>
            <tspan y="73" x="9" style="white-space:pre">private static final int </tspan>
            <tspan class="st4" style="white-space:pre">SERVER_COUNT</tspan>
            <tspan style="white-space:pre"> = 3; </tspan>
            <tspan y="88" x="9" style="white-space:pre">private static final Map&lt;Long, BackendServer> </tspan>
            <tspan class="st4" style="white-space:pre">serverInstances</tspan>
            <tspan style="white-space:pre"> = new HashMap&lt;>();</tspan>
            <tspan y="118" x="9" style="white-space:pre">static { </tspan>
            <tspan y="133" x="9" style="white-space:pre">    serverInstances.put(1L, new BackendServer(1L, "192.134.22.138:8080")); </tspan>
            <tspan y="148" x="9" style="white-space:pre">    serverInstances.put(2L, new BackendServer(2L, "192.134.22.139:8080")); </tspan>
            <tspan y="163" x="9" style="white-space:pre">    serverInstances.put(3L, new BackendServer(3L, "192.134.22.140:8080")); </tspan>
            <tspan y="178" x="9" style="white-space:pre">}</tspan>
            <tspan y="208" x="9" style="white-space:pre">private BackendServer(long serverNo, String serverAddress) { </tspan>
            <tspan y="223" x="9" style="white-space:pre">    this.serverNo = serverNo; </tspan>
            <tspan y="238" x="9" style="white-space:pre">    this.serverAddress = serverAddress; </tspan>
            <tspan y="253" x="9" style="white-space:pre">}</tspan>
            <tspan y="283" x="9" style="white-space:pre">public BackendServer getInstance(long serverNo) { </tspan>
            <tspan y="298" x="9" style="white-space:pre">    return serverInstances.get(serverNo); </tspan>
            <tspan y="313" x="9" style="white-space:pre">}</tspan>
            <tspan y="343" x="9" style="white-space:pre">public BackendServer </tspan>
            <tspan class="st4" style="white-space:pre">getRandomInstance</tspan>
            <tspan style="white-space:pre">() { </tspan>
            <tspan y="358" x="9" style="white-space:pre">    Random r = new Random(); </tspan>
            <tspan y="373" x="9" style="white-space:pre">    int no = r.nextInt(SERVER_COUNT)+1; </tspan>
            <tspan y="388" x="9" style="white-space:pre">    return serverInstances.get(no); }</tspan>
            <tspan y="403" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="354" ed:height="20.5" ed:layout="rightmap" id="274" transform="matrix(1,0,0,1,2221,2616)" ed:parentid="268">
        <path fill="none" d="M0,20.5L354,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">同一类型的只能创建一个对象，不同类型的可以创建多个对象。</tspan>
        </text>
    </g>
    <g ed:width="559.547" ed:height="20.5" ed:layout="rightmap" id="276" transform="matrix(1,0,0,1,2221,2643)" ed:parentid="268">
        <path fill="none" d="M0,20.5L559.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">同一个 logger name 获取到的对象实例是相同的，不同的 loggername 获取到的对象实例是不同的。</tspan>
        </text>
    </g>
    <g ed:width="203.938" ed:height="22.5" ed:layout="leftmap" id="278" transform="matrix(1,0,0,1,1125,116)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L203.9,0L203.9,22.5L0,22.5L0,0z"/>
        <path fill="none" d="M0,22.5L203.9,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">简单工厂(1个工厂生产1种商品)</tspan>
        </text>
    </g>
    <g ed:width="404.578" ed:height="22.5" ed:layout="leftmap" id="280" transform="matrix(1,0,0,1,925,488)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L404.6,0L404.6,22.5L0,22.5L0,0z"/>
        <path fill="none" d="M0,22.5L404.6,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="26" style="white-space:pre">工厂方法（每个工厂生产1种商品，商品有共同逻辑，也有特殊逻辑）</tspan>
        </text>
    </g>
    <g ed:width="456.531" ed:height="22.5" ed:layout="leftmap" id="282" transform="matrix(1,0,0,1,873,1017)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L456.5,0L456.5,22.5L0,22.5L0,0z"/>
        <path fill="none" d="M0,22.5L456.5,22.5" stroke="#696969" stroke-linejoin="round"/>
        <g transform="translate(7,2.25)">
            <use xlink:href="#flag1" transform="translate(0,0)"/>
        </g>
        <text class="st1">
            <tspan y="15.7" x="27" style="white-space:pre">抽象工厂（组装工厂：商品A1+商品B1、商品A2+商品B2、商品A3+商品B3）</tspan>
        </text>
    </g>
    <g ed:width="158.219" ed:height="20.5" ed:layout="leftmap" id="292" transform="matrix(1,0,0,1,1171,2300)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L158.2,0L158.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L158.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">实现一个依赖注入(DI)框架</tspan>
        </text>
    </g>
    <g ed:width="166.234" ed:height="20.5" ed:layout="leftmap" id="294" transform="matrix(1,0,0,1,978,1596)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L166.2,0L166.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L166.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">DI 容器的核心功能有哪些？</tspan>
        </text>
    </g>
    <g ed:width="182.031" ed:height="20.5" ed:layout="leftmap" id="296" transform="matrix(1,0,0,1,962,2465)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L182,0L182,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L182,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">如何实现一个简单的 DI 容器？</tspan>
        </text>
    </g>
    <g ed:width="182.031" ed:height="20.5" ed:layout="leftmap" id="298" transform="matrix(1,0,0,1,962,1431)" ed:parentid="292">
        <path fill="#ffffff" d="M0,0L182,0L182,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L182,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">工厂模式和 DI 容器有何区别？</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="300" transform="matrix(1,0,0,1,885,1488)" ed:parentid="294">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">配置解析</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="302" transform="matrix(1,0,0,1,885,1537)" ed:parentid="294">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">对象创建</tspan>
        </text>
    </g>
    <g ed:width="114" ed:height="20.5" ed:layout="leftmap" id="304" transform="matrix(1,0,0,1,837,1645)" ed:parentid="294">
        <path fill="#ffffff" d="M0,0L114,0L114,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L114,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">对象生命周期管理</tspan>
        </text>
    </g>
    <g ed:width="520.828" ed:height="20.5" ed:layout="leftmap" id="306" transform="matrix(1,0,0,1,577,59)" ed:parentid="278">
        <path fill="#ffffff" d="M0,0L520.8,0L520.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L520.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">大部分工厂类都是以“Factory”这个单词结尾的。工厂类中创建对象的方法一般都是 create 开头</tspan>
        </text>
    </g>
    <g ed:width="512.391" ed:height="109" ed:layout="leftmap" id="308" transform="matrix(1,0,0,1,586,86)" ed:parentid="278">
        <path fill="#ebebeb" d="M0,0L512.4,0L512.4,109L0,109L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st5">
            <tspan y="13" x="9" class="st6" style="white-space:pre">    public </tspan>
            <tspan style="white-space:pre">interface</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan class="st6" style="white-space:pre"> {  void execute();   }</tspan>
            <tspan y="28" x="9" class="st6" style="white-space:pre">    public class </tspan>
            <tspan class="st4" style="white-space:pre">ProductImpl1</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">implements</tspan>
            <tspan class="st6" style="white-space:pre"> Product {  public void execute() { ... ;}}</tspan>
            <tspan y="43" x="9" class="st6" style="white-space:pre">    public class </tspan>
            <tspan class="st4" style="white-space:pre">ProductFactory</tspan>
            <tspan class="st6" style="white-space:pre"> {  public </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan class="st6" style="white-space:pre"> create() {return new </tspan>
            <tspan class="st4" style="white-space:pre">ProductImpl1()</tspan>
            <tspan class="st6" style="white-space:pre">;}}</tspan>
            <tspan y="73" x="9" class="st6" style="white-space:pre">//main</tspan>
            <tspan y="88" x="9" class="st6" style="white-space:pre">Product product = ProductFactory.create();</tspan>
            <tspan y="103" x="9" class="st6" style="white-space:pre">product.execute();</tspan>
        </text>
    </g>
    <g ed:width="414" ed:height="20.5" ed:layout="leftmap" id="310" transform="matrix(1,0,0,1,484,242)" ed:parentid="280">
        <path fill="#ffffff" d="M0,0L414,0L414,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L414,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">为工厂类再创建一个简单工厂，也就是工厂的工厂，用来创建工厂类对象。</tspan>
        </text>
    </g>
    <g ed:width="174" ed:height="20.5" ed:layout="leftmap" id="312" transform="matrix(1,0,0,1,1155,1341)" ed:parentid="107">
        <path fill="#ffffff" d="M0,0L174,0L174,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L174,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">判断是否使用工厂模式的标准</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="314" transform="matrix(1,0,0,1,1062,1301)" ed:parentid="312">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">封装变化</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="316" transform="matrix(1,0,0,1,1062,1328)" ed:parentid="312">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">代码复用</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="leftmap" id="318" transform="matrix(1,0,0,1,1050,1355)" ed:parentid="312">
        <path fill="#ffffff" d="M0,0L78,0L78,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">隔离复杂性</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="leftmap" id="320" transform="matrix(1,0,0,1,1050,1382)" ed:parentid="312">
        <path fill="#ffffff" d="M0,0L78,0L78,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">控制复杂度</tspan>
        </text>
    </g>
    <g ed:width="408.203" ed:height="20.5" ed:layout="leftmap" id="322" transform="matrix(1,0,0,1,627,1301)" ed:parentid="314">
        <path fill="#ffffff" d="M0,0L408.2,0L408.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L408.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">创建逻辑有可能变化，封装成工厂类之后，创建逻辑的变更对调用者透明v</tspan>
        </text>
    </g>
    <g ed:width="246" ed:height="20.5" ed:layout="leftmap" id="324" transform="matrix(1,0,0,1,789,1328)" ed:parentid="316">
        <path fill="#ffffff" d="M0,0L246,0L246,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L246,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">创建代码抽离到独立的工厂类之后可以复用</tspan>
        </text>
    </g>
    <g ed:width="294" ed:height="20.5" ed:layout="leftmap" id="326" transform="matrix(1,0,0,1,729,1355)" ed:parentid="318">
        <path fill="#ffffff" d="M0,0L294,0L294,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L294,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">封装复杂的创建逻辑，调用者无需了解如何创建对象</tspan>
        </text>
    </g>
    <g ed:width="366" ed:height="20.5" ed:layout="leftmap" id="328" transform="matrix(1,0,0,1,657,1382)" ed:parentid="320">
        <path fill="#ffffff" d="M0,0L366,0L366,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L366,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">将创建代码抽离出来，让原本的函数或类职责更单一，代码更简洁</tspan>
        </text>
    </g>
    <g ed:width="286.234" ed:height="20.5" ed:layout="leftmap" id="330" transform="matrix(1,0,0,1,649,1409)" ed:parentid="298">
        <path fill="#ffffff" d="M0,0L286.2,0L286.2,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L286.2,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">DI 容器底层最基本的设计思路就是基于工厂模式的</tspan>
        </text>
    </g>
    <g ed:width="617.359" ed:height="37.5" ed:layout="leftmap" id="332" transform="matrix(1,0,0,1,318,1436)" ed:parentid="298">
        <path fill="#ffffff" d="M0,0L617.4,0L617.4,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L617.4,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">DI 容器相当于一个大的工厂类，负责在程序启动的时候，根据配置（要创建哪些类对象，每个类对象的创建需要</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">依赖哪些其他类对象）事先创建好对象。当应用程序需要使用某个类对象的时候，直接从容器中获取即可。</tspan>
        </text>
    </g>
    <g ed:width="596.1559999999999" ed:height="37.5" ed:layout="leftmap" id="334" transform="matrix(1,0,0,1,262,1480)" ed:parentid="300">
        <path fill="#ffffff" d="M0,0L596.2,0L596.2,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L596.2,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="7" style="white-space:pre">将需要由 DI 容器来创建的类对象和创建类对象的必要信息（使用哪个构造函数以及对应的构造函数参数都是</tspan>
            <tspan y="31.6" x="7" style="white-space:pre">什么等等），放到配置文件中。容器读取配置文件，根据配置文件提供的信息来创建对象。</tspan>
        </text>
    </g>
    <g ed:width="270" ed:height="20.5" ed:layout="leftmap" id="336" transform="matrix(1,0,0,1,588,1524)" ed:parentid="302">
        <path fill="#ffffff" d="M0,0L270,0L270,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L270,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">要将所有类对象的创建都放到一个工厂类中完成</tspan>
        </text>
    </g>
    <g ed:width="75.5313" ed:height="20.5" ed:layout="leftmap" id="338" transform="matrix(1,0,0,1,782,1551)" ed:parentid="302">
        <path fill="#ffffff" d="M0,0L75.5,0L75.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L75.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">“反射”机制</tspan>
        </text>
    </g>
    <g ed:width="534" ed:height="20.5" ed:layout="leftmap" id="340" transform="matrix(1,0,0,1,221,1551)" ed:parentid="338">
        <path fill="#ffffff" d="M0,0L534,0L534,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L534,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">它能在程序运行的过程中，动态地加载类、创建对象，不需要事先在代码中写死要创建哪些对象。</tspan>
        </text>
    </g>
    <g ed:width="51.8281" ed:height="18.5" ed:layout="leftmap" id="342" transform="matrix(1,0,0,1,758,1592)" ed:parentid="304">
        <path fill="#ffffff" d="M0,0L51.8,0L51.8,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L51.8,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre">scope</tspan>
        </text>
    </g>
    <g ed:width="117.984" ed:height="18.5" ed:layout="leftmap" id="344" transform="matrix(1,0,0,1,613,1579)" ed:parentid="342">
        <path fill="#ffffff" d="M0,0L118,0L118,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L118,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre">scope=prototype</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="20.5" ed:layout="leftmap" id="346" transform="matrix(1,0,0,1,436,1578)" ed:parentid="344">
        <path fill="#ffffff" d="M0,0L150,0L150,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L150,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">每次都返回新创建的对象</tspan>
        </text>
    </g>
    <g ed:width="119.063" ed:height="18.5" ed:layout="leftmap" id="348" transform="matrix(1,0,0,1,612,1606)" ed:parentid="342">
        <path fill="#ffffff" d="M0,0L119.1,0L119.1,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L119.1,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre">scope=singleton </tspan>
        </text>
    </g>
    <g ed:width="318" ed:height="20.5" ed:layout="leftmap" id="350" transform="matrix(1,0,0,1,267,1605)" ed:parentid="348">
        <path fill="#ffffff" d="M0,0L318,0L318,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L318,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">每次都返回同一个事先创建好的对象，即所谓的单例对象</tspan>
        </text>
    </g>
    <g ed:width="102" ed:height="20.5" ed:layout="leftmap" id="352" transform="matrix(1,0,0,1,708,1645)" ed:parentid="304">
        <path fill="#ffffff" d="M0,0L102,0L102,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L102,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">是否支持懒加载</tspan>
        </text>
    </g>
    <g ed:width="103.859" ed:height="18.5" ed:layout="leftmap" id="354" transform="matrix(1,0,0,1,577,1633)" ed:parentid="352">
        <path fill="#ffffff" d="M0,0L103.9,0L103.9,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L103.9,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre"> lazy-init=true</tspan>
        </text>
    </g>
    <g ed:width="104.5" ed:height="18.5" ed:layout="leftmap" id="356" transform="matrix(1,0,0,1,576,1660)" ed:parentid="352">
        <path fill="#ffffff" d="M0,0L104.5,0L104.5,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L104.5,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre"> lazy init=false</tspan>
        </text>
    </g>
    <g ed:width="210" ed:height="20.5" ed:layout="leftmap" id="358" transform="matrix(1,0,0,1,340,1632)" ed:parentid="354">
        <path fill="#ffffff" d="M0,0L210,0L210,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L210,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">对象在真正被使用到的时候才被创建</tspan>
        </text>
    </g>
    <g ed:width="210" ed:height="20.5" ed:layout="leftmap" id="360" transform="matrix(1,0,0,1,339,1659)" ed:parentid="356">
        <path fill="#ffffff" d="M0,0L210,0L210,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L210,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">对象在应用启动的时候就事先创建好</tspan>
        </text>
    </g>
    <g ed:width="190.219" ed:height="18.5" ed:layout="leftmap" id="362" transform="matrix(1,0,0,1,620,1687)" ed:parentid="304">
        <path fill="#ffffff" d="M0,0L190.2,0L190.2,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L190.2,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre"> init method=loadProperties()</tspan>
        </text>
    </g>
    <g ed:width="460.328" ed:height="20.5" ed:layout="leftmap" id="364" transform="matrix(1,0,0,1,132,1686)" ed:parentid="362">
        <path fill="#ffffff" d="M0,0L460.3,0L460.3,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L460.3,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">DI 容器在创建好对象之后，会主动调用 init-method 属性指定的方法来初始化对象</tspan>
        </text>
    </g>
    <g ed:width="228.938" ed:height="18.5" ed:layout="leftmap" id="366" transform="matrix(1,0,0,1,581,1714)" ed:parentid="304">
        <path fill="#ffffff" d="M0,0L228.9,0L228.9,18.5L0,18.5L0,0z"/>
        <path fill="none" d="M0,18.5L228.9,18.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="12.7" x="8" style="white-space:pre">destroy-method=updateConfigFile()</tspan>
        </text>
    </g>
    <g ed:width="532.813" ed:height="20.5" ed:layout="leftmap" id="368" transform="matrix(1,0,0,1,21,1713)" ed:parentid="366">
        <path fill="#ffffff" d="M0,0L532.8,0L532.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L532.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">在对象被最终销毁之前，DI 容器会主动调用 destroy-method 属性指定的方法来做一些清理工作</tspan>
        </text>
    </g>
    <g ed:width="502.5" ed:height="488" ed:layout="leftmap" id="371" transform="matrix(1,0,0,1,395,269)" ed:parentid="280">
        <path fill="#ebebeb" d="M0,0L502.5,0L502.5,488L0,488L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st7">
            <tspan y="13" x="9" class="st6" style="white-space:pre">    public </tspan>
            <tspan class="st8" style="white-space:pre">interface</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">Product</tspan>
            <tspan class="st6" style="white-space:pre"> {void execute();}</tspan>
            <tspan y="28" x="9" class="st6" style="white-space:pre">    public class </tspan>
            <tspan style="white-space:pre">ProductImpl1</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan class="st8" style="white-space:pre">implements</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">Product</tspan>
            <tspan class="st6" style="white-space:pre"> {  public void execute() { ... ;}}</tspan>
            <tspan y="43" x="9" class="st6" style="white-space:pre">    public class ProductImpl2 </tspan>
            <tspan class="st8" style="white-space:pre">implements</tspan>
            <tspan class="st6" style="white-space:pre"> Product {  public void execute() { ... ;}}</tspan>
            <tspan y="73" x="9" class="st6" style="white-space:pre">    public </tspan>
            <tspan class="st8" style="white-space:pre">abstract</tspan>
            <tspan class="st6" style="white-space:pre"> class </tspan>
            <tspan style="white-space:pre">AbstractProductFactory</tspan>
            <tspan class="st6" style="white-space:pre"> {</tspan>
            <tspan y="88" x="9" class="st6" style="white-space:pre">        public Product createProduct() {</tspan>
            <tspan y="103" x="9" class="st6" style="white-space:pre">            commonCreate();</tspan>
            <tspan y="118" x="9" class="st6" style="white-space:pre">            return specificCreate();</tspan>
            <tspan y="133" x="9" class="st6" style="white-space:pre">        }</tspan>
            <tspan y="150" x="9" class="st6" style="white-space:pre">        private void </tspan>
            <tspan style="white-space:pre">commonCreate()</tspan>
            <tspan class="st6" style="white-space:pre"> {System.out.println("生产产品的通用逻辑，修改");}</tspan>
            <tspan y="165" x="9" class="st6" style="white-space:pre">        protected </tspan>
            <tspan class="st9" style="white-space:pre">abstract</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">Product</tspan>
            <tspan class="st6" style="white-space:pre"> specificCreate();</tspan>
            <tspan y="180" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="210" x="9" class="st6" style="white-space:pre">    public class </tspan>
            <tspan style="white-space:pre">Product1Factory</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan class="st8" style="white-space:pre">extends</tspan>
            <tspan class="st6" style="white-space:pre"> </tspan>
            <tspan style="white-space:pre">AbstractProductFactory</tspan>
            <tspan class="st6" style="white-space:pre"> {</tspan>
            <tspan y="225" x="9" class="st6" style="white-space:pre">        private static final Product1Factory instance = new Product1Factory();</tspan>
            <tspan y="240" x="9" class="st6" style="white-space:pre">        private Product1Factory() {}</tspan>
            <tspan y="255" x="9" class="st6" style="white-space:pre">        public static Product1Factory </tspan>
            <tspan style="white-space:pre">get</tspan>
            <tspan class="st6" style="white-space:pre">() {  return instance;}</tspan>
            <tspan y="285" x="9" class="st6" style="white-space:pre">        @Override</tspan>
            <tspan y="300" x="9" class="st6" style="white-space:pre">        public Product specificCreate() {</tspan>
            <tspan y="317" x="9" class="st6" style="white-space:pre">            System.out.println("生产产品1的特殊逻辑");</tspan>
            <tspan y="332" x="9" class="st6" style="white-space:pre">            return </tspan>
            <tspan style="white-space:pre">new ProductImpl1()</tspan>
            <tspan class="st6" style="white-space:pre">;</tspan>
            <tspan y="347" x="9" class="st6" style="white-space:pre">        }</tspan>
            <tspan y="362" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="392" x="9" class="st6" style="white-space:pre">    public class Product2Factory </tspan>
            <tspan class="st8" style="white-space:pre">extends</tspan>
            <tspan class="st6" style="white-space:pre"> AbstractProductFactory {...}</tspan>
            <tspan y="422" x="9" class="st6" style="white-space:pre">     //main</tspan>
            <tspan y="437" x="9" class="st6" style="white-space:pre">     Product product1 = Product1Factory.get().createProduct();</tspan>
            <tspan y="452" x="9" class="st6" style="white-space:pre">     product1.execute();</tspan>
            <tspan y="467" x="9" class="st6" style="white-space:pre">     Product product2 = Product2Factory.get().createProduct();</tspan>
            <tspan y="482" x="9" class="st6" style="white-space:pre">     product2.execute();</tspan>
        </text>
    </g>
    <g ed:width="411.125" ed:height="531" ed:layout="leftmap" id="375" transform="matrix(1,0,0,1,435,763)" ed:parentid="282">
        <path fill="#ebebeb" d="M0,0L411.1,0L411.1,531L0,531L0,0z" stroke="#000000" stroke-linejoin="round"/>
        <text class="st10">
            <tspan y="13" x="9" class="st11" style="white-space:pre">    public </tspan>
            <tspan class="st12" style="white-space:pre">interface</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">ProductA</tspan>
            <tspan class="st11" style="white-space:pre"> { void execute(); }</tspan>
            <tspan y="28" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">ProductA1</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">ProductA</tspan>
            <tspan class="st11" style="white-space:pre"> {</tspan>
            <tspan y="43" x="9" class="st11" style="white-space:pre">        @Override</tspan>
            <tspan y="60" x="9" class="st11" style="white-space:pre">        public void execute() {System.out.println("产品A1的功能逻辑");}</tspan>
            <tspan y="75" x="9" class="st11" style="white-space:pre">    }</tspan>
            <tspan y="90" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">ProductA2</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">ProductA</tspan>
            <tspan class="st11" style="white-space:pre"> {}</tspan>
            <tspan y="105" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">ProductA3</tspan>
            <tspan class="st12" style="white-space:pre"> implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">ProductA</tspan>
            <tspan class="st11" style="white-space:pre"> {}</tspan>
            <tspan y="135" x="9" class="st11" style="white-space:pre">    public </tspan>
            <tspan class="st12" style="white-space:pre">interface </tspan>
            <tspan class="st13" style="white-space:pre">ProductB</tspan>
            <tspan class="st11" style="white-space:pre"> { void execute();}</tspan>
            <tspan y="150" x="9" class="st11" style="white-space:pre">    public class ProductB1 </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> ProductB {}</tspan>
            <tspan y="165" x="9" class="st11" style="white-space:pre">    public class ProductB2 </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> ProductB {}</tspan>
            <tspan y="180" x="9" class="st11" style="white-space:pre">    public class ProductB3 </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> ProductB {}</tspan>
            <tspan y="210" x="9" class="st11" style="white-space:pre">    public </tspan>
            <tspan class="st12" style="white-space:pre">interface</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">Factory</tspan>
            <tspan class="st11" style="white-space:pre"> {</tspan>
            <tspan y="225" x="9" class="st11" style="white-space:pre">        </tspan>
            <tspan style="white-space:pre">ProductA</tspan>
            <tspan class="st6" style="white-space:pre"> createProductA();</tspan>
            <tspan y="240" x="9" class="st11" style="white-space:pre">        </tspan>
            <tspan class="st13" style="white-space:pre">ProductB</tspan>
            <tspan class="st11" style="white-space:pre"> createProductB();</tspan>
            <tspan y="255" x="9" class="st11" style="white-space:pre">    }</tspan>
            <tspan y="285" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">Factory1</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">Factory</tspan>
            <tspan class="st11" style="white-space:pre"> {</tspan>
            <tspan y="300" x="9" class="st11" style="white-space:pre">        private static final Factory1 instance = new Factory1();</tspan>
            <tspan y="315" x="9" class="st11" style="white-space:pre">        private Factory1() {}</tspan>
            <tspan y="330" x="9" class="st11" style="white-space:pre">        public static Factory </tspan>
            <tspan class="st13" style="white-space:pre">get</tspan>
            <tspan class="st11" style="white-space:pre">() { return instance;}</tspan>
            <tspan y="345" x="9" class="st11" style="white-space:pre">        @Override</tspan>
            <tspan y="360" x="9" class="st11" style="white-space:pre">        public </tspan>
            <tspan class="st13" style="white-space:pre">ProductA</tspan>
            <tspan class="st11" style="white-space:pre"> createProductA() {return new ProductA1(); }</tspan>
            <tspan y="375" x="9" class="st11" style="white-space:pre">        @Override</tspan>
            <tspan y="390" x="9" class="st11" style="white-space:pre">        public </tspan>
            <tspan class="st13" style="white-space:pre">ProductB</tspan>
            <tspan class="st11" style="white-space:pre"> createProductB() {return new ProductB1();}</tspan>
            <tspan y="405" x="9" class="st11" style="white-space:pre">    }</tspan>
            <tspan y="420" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">Factory2</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">Factory</tspan>
            <tspan class="st11" style="white-space:pre"> {}</tspan>
            <tspan y="435" x="9" class="st11" style="white-space:pre">    public class </tspan>
            <tspan class="st13" style="white-space:pre">Factory3</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st12" style="white-space:pre">implements</tspan>
            <tspan class="st11" style="white-space:pre"> </tspan>
            <tspan class="st13" style="white-space:pre">Factory</tspan>
            <tspan class="st11" style="white-space:pre"> {}</tspan>
            <tspan y="465" x="9" class="st11" style="white-space:pre">    //</tspan>
            <tspan class="st13" style="white-space:pre">main</tspan>
            <tspan y="480" x="9" class="st11" style="white-space:pre">    ProductA productA1 = Factory1.get().createProductA();</tspan>
            <tspan y="495" x="9" class="st11" style="white-space:pre">    ProductB productB1 = Factory1.get().createProductB();</tspan>
            <tspan y="510" x="9" class="st11" style="white-space:pre">    productA1.execute();</tspan>
            <tspan y="525" x="9" class="st11" style="white-space:pre">    productB1.execute();</tspan>
        </text>
    </g>
    <g ed:width="430.406" ed:height="19" ed:layout="leftmap" id="378" transform="matrix(1,0,0,1,505,1740)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L430.4,0L430.4,19L0,19L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public interface </tspan>
            <tspan class="st4" style="white-space:pre">ApplicationContext</tspan>
            <tspan style="white-space:pre"> {  Object getBean(String beanId);  }</tspan>
        </text>
    </g>
    <g ed:width="352.828" ed:height="64" ed:layout="leftmap" id="380" transform="matrix(1,0,0,1,582,1765)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L352.8,0L352.8,64L0,64L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public interface </tspan>
            <tspan class="st4" style="white-space:pre">BeanConfigParser</tspan>
            <tspan style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" style="white-space:pre">    List&lt;BeanDefinition> parse(InputStream inputStream);</tspan>
            <tspan y="43" x="9" style="white-space:pre">    List&lt;BeanDefinition> parse(String configContent);</tspan>
            <tspan y="58" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="510.75" ed:height="231" ed:layout="leftmap" id="382" transform="matrix(1,0,0,1,424,1836)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L510.8,0L510.8,231L0,231L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st7">
            <tspan y="13" x="9" class="st6" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">ClassPathXmlApplicationContext</tspan>
            <tspan class="st6" style="white-space:pre"> implements </tspan>
            <tspan style="white-space:pre">ApplicationContext</tspan>
            <tspan class="st6" style="white-space:pre">{</tspan>
            <tspan y="28" x="9" class="st6" style="white-space:pre">    private BeansFactory beansFactory;</tspan>
            <tspan y="43" x="9" class="st6" style="white-space:pre">    private BeanConfigParser beanConfigParser;</tspan>
            <tspan y="75" x="9" class="st6" style="white-space:pre">    //构造方法调用loadBeanDefinitions</tspan>
            <tspan y="105" x="9" class="st6" style="white-space:pre">    private void </tspan>
            <tspan class="st14" style="white-space:pre">loadBeanDefinitions</tspan>
            <tspan class="st6" style="white-space:pre">(String configLocation){</tspan>
            <tspan y="120" x="9" class="st6" style="white-space:pre">            InputStream in = this.getClass().getResourceAsStream("/" + configLocation);</tspan>
            <tspan y="135" x="9" class="st6" style="white-space:pre">            List&lt;BeanDefinition> beanDefinitions = beanConfigParser.</tspan>
            <tspan class="st14" style="white-space:pre">parse</tspan>
            <tspan class="st6" style="white-space:pre">(in);</tspan>
            <tspan y="150" x="9" class="st6" style="white-space:pre">            </tspan>
            <tspan style="white-space:pre">beansFactory</tspan>
            <tspan class="st6" style="white-space:pre">.</tspan>
            <tspan class="st14" style="white-space:pre">addBeanDefinitions</tspan>
            <tspan class="st6" style="white-space:pre">(beanDefinitions);</tspan>
            <tspan y="165" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="195" x="9" class="st6" style="white-space:pre">    @Override</tspan>
            <tspan y="210" x="9" class="st6" style="white-space:pre">    public Object getBean(String beanId) {return beansFactory.getBean(beanId);}</tspan>
            <tspan y="225" x="9" class="st6" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="851.859" ed:height="139" ed:layout="leftmap" id="384" transform="matrix(1,0,0,1,83,2073)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L851.9,0L851.9,139L0,139L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class </tspan>
            <tspan class="st4" style="white-space:pre">XmlBeanConfigParser</tspan>
            <tspan style="white-space:pre"> implements </tspan>
            <tspan class="st4" style="white-space:pre">BeanConfigParser</tspan>
            <tspan style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" style="white-space:pre">    @Override</tspan>
            <tspan y="43" x="9" style="white-space:pre">    public List&lt;BeanDefinition> parse(InputStream inputStream) {String content = null;return  parse(content);</tspan>
            <tspan y="58" x="9" style="white-space:pre">    }</tspan>
            <tspan y="88" x="9" style="white-space:pre">    @Override</tspan>
            <tspan y="103" x="9" style="white-space:pre">    public List&lt;BeanDefinition> parse(String configContent) {List&lt;BeanDefinition> beanDefinitions = new ArrayList&lt;>();return beanDefinitions;</tspan>
            <tspan y="118" x="9" style="white-space:pre">    }</tspan>
            <tspan y="133" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="439.797" ed:height="244" ed:layout="leftmap" id="386" transform="matrix(1,0,0,1,495,2219)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L439.8,0L439.8,244L0,244L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class </tspan>
            <tspan class="st4" style="white-space:pre">BeanDefinition</tspan>
            <tspan style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" style="white-space:pre">    private String id;</tspan>
            <tspan y="43" x="9" style="white-space:pre">    private String className;</tspan>
            <tspan y="58" x="9" style="white-space:pre">    private List&lt;ConstructorArg> constructorArgs = new ArrayList&lt;>();</tspan>
            <tspan y="73" x="9" style="white-space:pre">    private Scope scope = Scope.SINGLETON;</tspan>
            <tspan y="88" x="9" style="white-space:pre">    private boolean lazyInit = false;</tspan>
            <tspan y="118" x="9" style="white-space:pre">    public boolean isSingleton() {return scope.equals(Scope.SINGLETON);}</tspan>
            <tspan y="148" x="9" style="white-space:pre">    public static enum </tspan>
            <tspan class="st4" style="white-space:pre">Scope</tspan>
            <tspan style="white-space:pre"> {SINGLETON,PROTOTYPE}</tspan>
            <tspan y="163" x="9" style="white-space:pre">    public static class </tspan>
            <tspan class="st4" style="white-space:pre">ConstructorArg</tspan>
            <tspan style="white-space:pre"> {</tspan>
            <tspan y="178" x="9" style="white-space:pre">        private boolean ref;</tspan>
            <tspan y="193" x="9" style="white-space:pre">        private Class type;</tspan>
            <tspan y="208" x="9" style="white-space:pre">        private Object arg;</tspan>
            <tspan y="223" x="9" style="white-space:pre">    }</tspan>
            <tspan y="238" x="9" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="632.703" ed:height="616" ed:layout="leftmap" id="388" transform="matrix(1,0,0,1,302,2469)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L632.7,0L632.7,616L0,616L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st7">
            <tspan y="13" x="9" class="st6" style="white-space:pre">public class </tspan>
            <tspan style="white-space:pre">BeansFactory</tspan>
            <tspan class="st6" style="white-space:pre"> {</tspan>
            <tspan y="28" x="9" class="st6" style="white-space:pre">    private ConcurrentHashMap&lt;String, Object> singletonObjects = new ConcurrentHashMap&lt;>();</tspan>
            <tspan y="43" x="9" class="st6" style="white-space:pre">    private ConcurrentHashMap&lt;String, BeanDefinition> beanDefinitions = new ConcurrentHashMap&lt;>();</tspan>
            <tspan y="73" x="9" class="st6" style="white-space:pre">    public void </tspan>
            <tspan class="st14" style="white-space:pre">addBeanDefinitions</tspan>
            <tspan class="st6" style="white-space:pre">(List&lt;BeanDefinition> beanDefinitionList) throws Exception {</tspan>
            <tspan y="88" x="9" class="st6" style="white-space:pre">        for (BeanDefinition beanDefinition : beanDefinitionList) {</tspan>
            <tspan y="103" x="9" class="st6" style="white-space:pre">            this.beanDefinitions.putIfAbsent(beanDefinition.getId(), beanDefinition);</tspan>
            <tspan y="118" x="9" class="st6" style="white-space:pre">        }</tspan>
            <tspan y="148" x="9" class="st6" style="white-space:pre">        for (BeanDefinition beanDefinition : beanDefinitionList) {</tspan>
            <tspan y="163" x="9" class="st6" style="white-space:pre">            if (beanDefinition.isLazyInit() == false &amp;&amp; beanDefinition.isSingleton()) {</tspan>
            <tspan y="178" x="9" class="st6" style="white-space:pre">                </tspan>
            <tspan style="white-space:pre">createBean</tspan>
            <tspan class="st6" style="white-space:pre">(beanDefinition);</tspan>
            <tspan y="193" x="9" class="st6" style="white-space:pre">            }</tspan>
            <tspan y="208" x="9" class="st6" style="white-space:pre">        }</tspan>
            <tspan y="223" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="253" x="9" class="st6" style="white-space:pre">    public Object </tspan>
            <tspan class="st14" style="white-space:pre">getBean</tspan>
            <tspan class="st6" style="white-space:pre">(String beanId) {</tspan>
            <tspan y="268" x="9" class="st6" style="white-space:pre">        BeanDefinition beanDefinition = beanDefinitions.get(beanId);</tspan>
            <tspan y="283" x="9" class="st6" style="white-space:pre">        return createBean(beanDefinition);</tspan>
            <tspan y="298" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="328" x="9" class="st6" style="white-space:pre">    protected Object </tspan>
            <tspan class="st14" style="white-space:pre">createBean</tspan>
            <tspan class="st6" style="white-space:pre">(BeanDefinition beanDefinition) throws Exception {</tspan>
            <tspan y="343" x="9" class="st6" style="white-space:pre">        if (beanDefinition.isSingleton() &amp;&amp; singletonObjects.contains(beanDefinition.getId())){</tspan>
            <tspan y="358" x="9" class="st6" style="white-space:pre">            return singletonObjects.get(beanDefinition.getId());</tspan>
            <tspan y="373" x="9" class="st6" style="white-space:pre">        }</tspan>
            <tspan y="405" x="9" class="st6" style="white-space:pre">        //通过反射得到class 和构造函数的参数</tspan>
            <tspan y="422" x="9" class="st6" style="white-space:pre">        //参数 == null, 返回 beanClass.newInstance();</tspan>
            <tspan y="439" x="9" class="st6" style="white-space:pre">        //参数 != null,</tspan>
            <tspan y="456" x="9" class="st6" style="white-space:pre">            //如果构造函数的参数不是ref。得到参数的类型和值。</tspan>
            <tspan y="473" x="9" class="st6" style="white-space:pre">            //如果参数是ref，递归 createBean()</tspan>
            <tspan y="490" x="9" class="st6" style="white-space:pre">            //返回 beanClass.getConstructor(argClasses).newInstance(argObjects);</tspan>
            <tspan y="505" x="9" class="st6" style="white-space:pre">            </tspan>
            <tspan y="520" x="9" class="st6" style="white-space:pre">            if (bean != null &amp;&amp; beanDefinition.isSingleton()) {</tspan>
            <tspan y="535" x="9" class="st6" style="white-space:pre">                singletonObjects.putIfAbsent(beanDefinition.getId(), bean);</tspan>
            <tspan y="550" x="9" class="st6" style="white-space:pre">                return singletonObjects.get(beanDefinition.getId());</tspan>
            <tspan y="565" x="9" class="st6" style="white-space:pre">            }</tspan>
            <tspan y="580" x="9" class="st6" style="white-space:pre">            return bean;</tspan>
            <tspan y="595" x="9" class="st6" style="white-space:pre">    }</tspan>
            <tspan y="610" x="9" class="st6" style="white-space:pre">}</tspan>
        </text>
    </g>
    <g ed:width="350.766" ed:height="79" ed:layout="leftmap" id="390" transform="matrix(1,0,0,1,584,3092)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L350.8,0L350.8,79L0,79L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">&lt;beans></tspan>
            <tspan y="28" x="9" style="white-space:pre">    &lt;bean id="rateLimiter" class="com.xzg.RateLimiter"></tspan>
            <tspan y="43" x="9" style="white-space:pre">        &lt;constructor-arg ref="redisCounter"/></tspan>
            <tspan y="58" x="9" style="white-space:pre">    &lt;/bean></tspan>
            <tspan y="73" x="9" style="white-space:pre">&lt;/beans></tspan>
        </text>
    </g>
    <g ed:width="565.625" ed:height="34" ed:layout="leftmap" id="392" transform="matrix(1,0,0,1,369,3177)" ed:parentid="296">
        <path fill="#ebebeb" d="M0,0L565.6,0L565.6,34L0,34L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("beans.xml");</tspan>
            <tspan y="28" x="9" style="white-space:pre">Object rateLimiter = applicationContext.getBean("rateLimiter");</tspan>
        </text>
    </g>
    <g ed:width="150" ed:height="20.5" ed:layout="rightmap" id="395" transform="matrix(1,0,0,1,2040,2820)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L150,0L150,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L150,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">为什么需要构造器模式？</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="rightmap" id="397" transform="matrix(1,0,0,1,2040,3552)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">与工厂模式有何区别？</tspan>
        </text>
    </g>
    <g ed:width="420.938" ed:height="20.5" ed:layout="rightmap" id="399" transform="matrix(1,0,0,1,2217,2736)" ed:parentid="395">
        <path fill="#ffffff" d="M0,0L420.9,0L420.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L420.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">创建一个对象最常用的方式是，使用 new 关键字调用类的构造函数来完成。</tspan>
        </text>
    </g>
    <g ed:width="265.875" ed:height="37.5" ed:layout="rightmap" id="401" transform="matrix(1,0,0,1,2217,2825)" ed:parentid="395">
        <path fill="#ffffff" d="M0,0L265.9,0L265.9,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L265.9,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">定义一个资源池配置类 ResourcePoolConfig</tspan>
            <tspan y="31.6" x="8" style="white-space:pre"> maxTotal、maxIdle、minIdle 不是必填变量</tspan>
        </text>
    </g>
    <g ed:width="539.641" ed:height="37.5" ed:layout="rightmap" id="403" transform="matrix(1,0,0,1,2510,2763)" ed:parentid="401">
        <path fill="#ffffff" d="M0,0L539.6,0L539.6,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L539.6,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="7" style="white-space:pre">最常见、最容易想到的实现思路：在创建 ResourcePoolConfig 对象的时候，通过构造函数给这几</tspan>
            <tspan y="31.6" x="7" style="white-space:pre">个参数传递 null值，来表示使用默认值</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="405" transform="matrix(1,0,0,1,3077,2763)" ed:parentid="403">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">如果可配置项逐渐增多，构造函数的参数列表会变得很长。就容易搞错各参数的顺序，传递进</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">错误的参数值</tspan>
        </text>
    </g>
    <g ed:width="326.641" ed:height="20.5" ed:layout="rightmap" id="407" transform="matrix(1,0,0,1,2510,2856)" ed:parentid="401">
        <path fill="#ffffff" d="M0,0L326.6,0L326.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L326.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">通过构造函数设置必填项，通过 set() 方法设置可选配置项</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="rightmap" id="411" transform="matrix(1,0,0,1,2864,2807)" ed:parentid="407">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">如果必填的配置项有很多，把这些必填配置项都放到构造函数中设置，那构造函数就又会出现</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">参数列表很长的问题</tspan>
        </text>
    </g>
    <g ed:width="198" ed:height="20.5" ed:layout="rightmap" id="413" transform="matrix(1,0,0,1,2864,2851)" ed:parentid="407">
        <path fill="#ffffff" d="M0,0L198,0L198,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L198,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">假设配置项之间有一定的依赖关系</tspan>
        </text>
    </g>
    <g ed:width="481.875" ed:height="20.5" ed:layout="rightmap" id="415" transform="matrix(1,0,0,1,3089,2851)" ed:parentid="413">
        <path fill="#ffffff" d="M0,0L481.9,0L481.9,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L481.9,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">如果用户设置了 maxTotal、maxIdle、minIdle 其中一个，就必须显式地设置另外两个</tspan>
        </text>
    </g>
    <g ed:width="198" ed:height="20.5" ed:layout="rightmap" id="417" transform="matrix(1,0,0,1,2864,2878)" ed:parentid="407">
        <path fill="#ffffff" d="M0,0L198,0L198,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L198,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">或者配置项之间有一定的约束条件</tspan>
        </text>
    </g>
    <g ed:width="249.469" ed:height="20.5" ed:layout="rightmap" id="419" transform="matrix(1,0,0,1,3089,2878)" ed:parentid="417">
        <path fill="#ffffff" d="M0,0L249.5,0L249.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L249.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">maxIdle 和 minIdle 要小于等于 maxTotal</tspan>
        </text>
    </g>
    <g ed:width="549.578" ed:height="20.5" ed:layout="rightmap" id="421" transform="matrix(1,0,0,1,2864,2905)" ed:parentid="407">
        <path fill="#ffffff" d="M0,0L549.6,0L549.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L549.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">希望 ResourcePoolConfig 类对象是不可变对象，即对象在创建好之后，就不能再修改内部的属性值</tspan>
        </text>
    </g>
    <g ed:width="185.984" ed:height="20.5" ed:layout="rightmap" id="423" transform="matrix(1,0,0,1,2040,3197)" ed:parentid="109">
        <path fill="#ffffff" d="M0,0L186,0L186,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L186,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">把校验逻辑放置到 Builder 类中</tspan>
        </text>
    </g>
    <g ed:width="314.641" ed:height="20.5" ed:layout="rightmap" id="425" transform="matrix(1,0,0,1,2253,2932)" ed:parentid="423">
        <path fill="#ffffff" d="M0,0L314.6,0L314.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L314.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">先创建建造者，并且通过 set() 方法设置建造者的变量值</tspan>
        </text>
    </g>
    <g ed:width="482.844" ed:height="20.5" ed:layout="rightmap" id="427" transform="matrix(1,0,0,1,2253,2959)" ed:parentid="423">
        <path fill="#ffffff" d="M0,0L482.8,0L482.8,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L482.8,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">然后在使用 build() 方法真正创建对象之前，做集中的校验，校验通过之后才会创建对象</tspan>
        </text>
    </g>
    <g ed:width="624.6559999999999" ed:height="20.5" ed:layout="rightmap" id="429" transform="matrix(1,0,0,1,2253,2986)" ed:parentid="423">
        <path fill="#ffffff" d="M0,0L624.7,0L624.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L624.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">把 ResourcePoolConfig 的构造函数改为 private 私有权限。只能通过建造者来创建 ResourcePoolConfig 类对象</tspan>
        </text>
    </g>
    <g ed:width="494.422" ed:height="20.5" ed:layout="rightmap" id="431" transform="matrix(1,0,0,1,2253,3013)" ed:parentid="423">
        <path fill="#ffffff" d="M0,0L494.4,0L494.4,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L494.4,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">ResourcePoolConfig 没有提供任何 set() 方法，这样创建出来的对象就是不可变对象了。</tspan>
        </text>
    </g>
    <g ed:width="902.5309999999999" ed:height="443" ed:layout="rightmap" id="433" transform="matrix(1,0,0,1,2253,3040)" ed:parentid="423">
        <path fill="#ebebeb" d="M0,0L902.5,0L902.5,443L0,443L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class </tspan>
            <tspan class="st4" style="white-space:pre">ResourcePoolConfig</tspan>
            <tspan style="white-space:pre"> { </tspan>
            <tspan y="28" x="9" style="white-space:pre">    private String name; </tspan>
            <tspan y="43" x="9" style="white-space:pre">    private int maxTotal; </tspan>
            <tspan y="58" x="9" style="white-space:pre">    private int maxIdle; </tspan>
            <tspan y="73" x="9" style="white-space:pre">    private int minIdle; </tspan>
            <tspan y="103" x="9" style="white-space:pre">    private ResourcePoolConfig(</tspan>
            <tspan class="st4" style="white-space:pre">Builder</tspan>
            <tspan style="white-space:pre"> builder) { </tspan>
            <tspan y="118" x="9" style="white-space:pre">        this.name = builder.name; this.maxTotal = builder.maxTotal; this.maxIdle = builder.maxIdle; this.minIdle = builder.minIdle;</tspan>
            <tspan y="133" x="9" style="white-space:pre">    }</tspan>
            <tspan y="163" x="9" style="white-space:pre">    public static class </tspan>
            <tspan class="st4" style="white-space:pre">Builder</tspan>
            <tspan style="white-space:pre"> { </tspan>
            <tspan y="178" x="9" style="white-space:pre">        private static final int DEFAULT_MAX_TOTAL = 8; </tspan>
            <tspan y="193" x="9" style="white-space:pre">        private static final int DEFAULT_MAX_IDLE = 8; </tspan>
            <tspan y="208" x="9" style="white-space:pre">        private static final int DEFAULT_MIN_IDLE = 0;</tspan>
            <tspan y="238" x="9" style="white-space:pre">        private String name; </tspan>
            <tspan y="253" x="9" style="white-space:pre">        private int maxTotal = DEFAULT_MAX_TOTAL; </tspan>
            <tspan y="268" x="9" style="white-space:pre">        private int maxIdle = DEFAULT_MAX_IDLE; </tspan>
            <tspan y="283" x="9" style="white-space:pre">        private int minIdle = DEFAULT_MIN_IDLE;</tspan>
            <tspan y="313" x="9" style="white-space:pre">        public </tspan>
            <tspan class="st4" style="white-space:pre">ResourcePoolConfig</tspan>
            <tspan style="white-space:pre"> </tspan>
            <tspan class="st4" style="white-space:pre">build</tspan>
            <tspan style="white-space:pre">() { </tspan>
            <tspan y="330" x="9" style="white-space:pre">            // 校验逻辑放到这里来做，包括必填项校验、依赖关系校验、约束条件校验等</tspan>
            <tspan y="345" x="9" style="white-space:pre">            return new ResourcePoolConfig(this); </tspan>
            <tspan y="360" x="9" style="white-space:pre">        }</tspan>
            <tspan y="377" x="9" style="white-space:pre">        。。。setter。。。</tspan>
            <tspan y="392" x="9" style="white-space:pre">    }</tspan>
            <tspan y="422" x="9" style="white-space:pre">//main</tspan>
            <tspan y="437" x="9" style="white-space:pre">ResourcePoolConfig config = new </tspan>
            <tspan class="st4" style="white-space:pre">ResourcePoolConfig</tspan>
            <tspan style="white-space:pre">.</tspan>
            <tspan class="st4" style="white-space:pre">Builder</tspan>
            <tspan style="white-space:pre">() .setName("dbconnectionpool") .setMaxTotal(16) .setMaxIdle(10) .setMinIdle(12) .build();</tspan>
        </text>
    </g>
    <g ed:width="78" ed:height="20.5" ed:layout="rightmap" id="435" transform="matrix(1,0,0,1,2205,3503)" ed:parentid="397">
        <path fill="#ffffff" d="M0,0L78,0L78,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L78,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">建造者模式</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="rightmap" id="437" transform="matrix(1,0,0,1,2205,3557)" ed:parentid="397">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">工厂模式</tspan>
        </text>
    </g>
    <g ed:width="702" ed:height="20.5" ed:layout="rightmap" id="439" transform="matrix(1,0,0,1,2298,3570)" ed:parentid="437">
        <path fill="#ffffff" d="M0,0L702,0L702,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L702,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">工厂模式是用来创建不同但是相关类型的对象（继承同一父类或者接口的一组子类），由给定的参数来决定创建哪种类型的对象。</tspan>
        </text>
    </g>
    <g ed:width="186" ed:height="20.5" ed:layout="rightmap" id="441" transform="matrix(1,0,0,1,2298,3543)" ed:parentid="437">
        <path fill="#ffffff" d="M0,0L186,0L186,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L186,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">由工厂类来负责对象创建的工作</tspan>
        </text>
    </g>
    <g ed:width="198" ed:height="20.5" ed:layout="rightmap" id="443" transform="matrix(1,0,0,1,2310,3489)" ed:parentid="435">
        <path fill="#ffffff" d="M0,0L198,0L198,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L198,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">让建造者类来负责对象的创建工作</tspan>
        </text>
    </g>
    <g ed:width="483.531" ed:height="20.5" ed:layout="rightmap" id="445" transform="matrix(1,0,0,1,2310,3516)" ed:parentid="435">
        <path fill="#ffffff" d="M0,0L483.5,0L483.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L483.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">用来创建一种类型的复杂对象，通过设置不同的可选参数，“定制化”地创建不同的对象。</tspan>
        </text>
    </g>
    <g ed:width="714" ed:height="37.5" ed:layout="rightmap" id="447" transform="matrix(1,0,0,1,2205,3597)" ed:parentid="397">
        <path fill="#ffffff" d="M0,0L714,0L714,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L714,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">顾客走进一家餐馆点餐，我们利用工厂模式，根据用户不同的选择，来制作不同的食物，比如披萨、汉堡、沙拉。</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">对于披萨来说，用户又有各种配料可以定制，比如奶酪、西红柿、起司，我们通过建造者模式根据用户选择的不同配料来制作披萨。</tspan>
        </text>
    </g>
    <g ed:width="138" ed:height="20.5" ed:layout="leftmap" id="450" transform="matrix(1,0,0,1,1191,3280)" ed:parentid="111">
        <path fill="#ffffff" d="M0,0L138,0L138,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L138,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">原型模式的原理与应用</tspan>
        </text>
    </g>
    <g ed:width="222" ed:height="20.5" ed:layout="leftmap" id="452" transform="matrix(1,0,0,1,1107,3459)" ed:parentid="111">
        <path fill="#ffffff" d="M0,0L222,0L222,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L222,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">原型模式的实现方式：深拷贝和浅拷贝</tspan>
        </text>
    </g>
    <g ed:width="510" ed:height="37.5" ed:layout="leftmap" id="454" transform="matrix(1,0,0,1,654,3244)" ed:parentid="450">
        <path fill="#ffffff" d="M0,0L510,0L510,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L510,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">如果对象的创建成本比较大，而同一个类的不同对象之间差别不大（大部分字段都相同）</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">利用对</tspan>
            <tspan class="st4" style="white-space:pre">已有对象</tspan>
            <tspan style="white-space:pre">（原型）进行</tspan>
            <tspan class="st4" style="white-space:pre">复制</tspan>
            <tspan style="white-space:pre">（拷贝）的方式来创建新对象，以达到节省创建时间的目的</tspan>
        </text>
    </g>
    <g ed:width="183.531" ed:height="20.5" ed:layout="leftmap" id="456" transform="matrix(1,0,0,1,981,3302)" ed:parentid="450">
        <path fill="#ffffff" d="M0,0L183.5,0L183.5,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L183.5,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">何为“对象的创建成本比较大”？</tspan>
        </text>
    </g>
    <g ed:width="390" ed:height="20.5" ed:layout="leftmap" id="458" transform="matrix(1,0,0,1,564,3288)" ed:parentid="456">
        <path fill="#ffffff" d="M0,0L390,0L390,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L390,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">对象中的数据需要经过复杂的计算才能得到（比如排序、计算哈希值）</tspan>
        </text>
    </g>
    <g ed:width="352.656" ed:height="20.5" ed:layout="leftmap" id="460" transform="matrix(1,0,0,1,601,3315)" ed:parentid="456">
        <path fill="#ffffff" d="M0,0L352.7,0L352.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L352.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">需要从 RPC、网络、数据库、文件系统等非常慢速的 IO 中读取</tspan>
        </text>
    </g>
    <g ed:width="54" ed:height="20.5" ed:layout="leftmap" id="462" transform="matrix(1,0,0,1,1026,3369)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L54,0L54,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L54,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">浅拷贝</tspan>
        </text>
    </g>
    <g ed:width="54" ed:height="20.5" ed:layout="leftmap" id="464" transform="matrix(1,0,0,1,1026,3472)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L54,0L54,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L54,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">深拷贝</tspan>
        </text>
    </g>
    <g ed:width="142.656" ed:height="20.5" ed:layout="leftmap" id="466" transform="matrix(1,0,0,1,857,3342)" ed:parentid="462">
        <path fill="#ffffff" d="M0,0L142.7,0L142.7,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L142.7,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">Object类的clone()方法</tspan>
        </text>
    </g>
    <g ed:width="666" ed:height="20.5" ed:layout="leftmap" id="468" transform="matrix(1,0,0,1,333,3369)" ed:parentid="462">
        <path fill="#ffffff" d="M0,0L666,0L666,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L666,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">它只会拷贝对象中的基本数据类型的数据以及引用对象的内存地址，不会递归地复制引用对象，以及引用对象的引用对象…</tspan>
        </text>
    </g>
    <g ed:width="186" ed:height="20.5" ed:layout="leftmap" id="470" transform="matrix(1,0,0,1,813,3396)" ed:parentid="462">
        <path fill="#ffffff" d="M0,0L186,0L186,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L186,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">修改拷贝数据，原数据也会改变</tspan>
        </text>
    </g>
    <g ed:width="514" ed:height="37.5" ed:layout="leftmap" id="472" transform="matrix(1,0,0,1,368,3450)" ed:parentid="474">
        <path fill="#ffffff" d="M0,0L514,0L514,37.5L0,37.5L0,0z"/>
        <path fill="none" d="M0,37.5L514,37.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.6" x="8" style="white-space:pre">1、递归拷贝对象、对象的引用对象以及引用对象的引用对象……直到要拷贝的对象只包含基</tspan>
            <tspan y="31.6" x="8" style="white-space:pre">本数据类型数据，没有引用对象为止。</tspan>
        </text>
    </g>
    <g ed:width="90" ed:height="20.5" ed:layout="leftmap" id="474" transform="matrix(1,0,0,1,909,3472)" ed:parentid="464">
        <path fill="#ffffff" d="M0,0L90,0L90,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L90,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">实现深拷贝：</tspan>
        </text>
    </g>
    <g ed:width="289.578" ed:height="20.5" ed:layout="leftmap" id="476" transform="matrix(1,0,0,1,593,3494)" ed:parentid="474">
        <path fill="#ffffff" d="M0,0L289.6,0L289.6,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L289.6,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="7" style="white-space:pre">2、先将对象序列化，然后再反序列化成新的对象。</tspan>
        </text>
    </g>
    <g ed:width="222" ed:height="20.5" ed:layout="leftmap" id="480" transform="matrix(1,0,0,1,777,3521)" ed:parentid="464">
        <path fill="#ffffff" d="M0,0L222,0L222,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L222,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">深拷贝都要比浅拷贝耗时、耗内存空间</tspan>
        </text>
    </g>
    <g ed:width="210" ed:height="20.5" ed:layout="leftmap" id="482" transform="matrix(1,0,0,1,789,3423)" ed:parentid="464">
        <path fill="#ffffff" d="M0,0L210,0L210,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L210,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">得到的是一份完完全全独立的对象。</tspan>
        </text>
    </g>
    <g ed:width="378" ed:height="20.5" ed:layout="leftmap" id="484" transform="matrix(1,0,0,1,702,3548)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L378,0L378,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L378,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">如果要拷贝的对象是</tspan>
            <tspan class="st4" style="white-space:pre">不可变对象</tspan>
            <tspan style="white-space:pre">，浅拷贝共享不可变对象是没问题的</tspan>
        </text>
    </g>
    <g ed:width="558" ed:height="20.5" ed:layout="leftmap" id="486" transform="matrix(1,0,0,1,522,3575)" ed:parentid="452">
        <path fill="#ffffff" d="M0,0L558,0L558,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L558,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">但对于</tspan>
            <tspan class="st4" style="white-space:pre">可变对象</tspan>
            <tspan style="white-space:pre">来说，浅拷贝得到的对象和原始对象会</tspan>
            <tspan class="st4" style="white-space:pre">共享部分数据</tspan>
            <tspan style="white-space:pre">，就有可能出现数据被修改的风险</tspan>
        </text>
    </g>
    <g ed:width="66" ed:height="20.5" ed:layout="leftmap" id="488" transform="matrix(1,0,0,1,1263,3842)" ed:parentid="111">
        <path fill="#ffffff" d="M0,0L66,0L66,20.5L0,20.5L0,0z"/>
        <path fill="none" d="M0,20.5L66,20.5" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="14.7" x="8" style="white-space:pre">代码实现</tspan>
        </text>
    </g>
    <g ed:width="413.313" ed:height="184" ed:layout="leftmap" id="490" transform="matrix(1,0,0,1,823,3602)" ed:parentid="488">
        <path fill="#ebebeb" d="M0,0L413.3,0L413.3,184L0,184L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">    public class </tspan>
            <tspan class="st4" style="white-space:pre">Component</tspan>
            <tspan style="white-space:pre">{</tspan>
            <tspan y="28" x="9" style="white-space:pre">        private String name;</tspan>
            <tspan y="58" x="9" style="white-space:pre">        public Component(String name) {this.name = name;}</tspan>
            <tspan y="73" x="9" style="white-space:pre">        public String getName() {return name;}</tspan>
            <tspan y="88" x="9" style="white-space:pre">        public void setName(String name) { this.name = name;}</tspan>
            <tspan y="118" x="9" style="white-space:pre">        @Override</tspan>
            <tspan y="133" x="9" style="white-space:pre">        protected Object </tspan>
            <tspan class="st4" style="white-space:pre">clone</tspan>
            <tspan style="white-space:pre">() throws CloneNotSupportedException{</tspan>
            <tspan y="148" x="9" style="white-space:pre">            return new </tspan>
            <tspan class="st4" style="white-space:pre">Component</tspan>
            <tspan style="white-space:pre">(getName());</tspan>
            <tspan y="163" x="9" style="white-space:pre">        }</tspan>
            <tspan y="178" x="9" style="white-space:pre">    }</tspan>
        </text>
    </g>
    <g ed:width="657.016" ed:height="310" ed:layout="leftmap" id="492" transform="matrix(1,0,0,1,579,3793)" ed:parentid="488">
        <path fill="#ebebeb" d="M0,0L657,0L657,310L0,310L0,0z" stroke="#696969" stroke-linejoin="round"/>
        <text class="st1">
            <tspan y="13" x="9" style="white-space:pre">public class </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan style="white-space:pre">{</tspan>
            <tspan y="28" x="9" style="white-space:pre">        private String name;</tspan>
            <tspan y="43" x="9" style="white-space:pre">        private </tspan>
            <tspan class="st4" style="white-space:pre">Component</tspan>
            <tspan style="white-space:pre"> component;</tspan>
            <tspan y="73" x="9" style="white-space:pre">        public </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan style="white-space:pre">(String name, </tspan>
            <tspan class="st4" style="white-space:pre">Component</tspan>
            <tspan style="white-space:pre"> component) {this.name = name;this.component = component;}</tspan>
            <tspan y="88" x="9" style="white-space:pre">        public String getName() {return name;}</tspan>
            <tspan y="103" x="9" style="white-space:pre">        public void setName(String name) {this.name = name;}</tspan>
            <tspan y="118" x="9" style="white-space:pre">        public Component getComponent() {return component;}</tspan>
            <tspan y="133" x="9" style="white-space:pre">        public void setComponent(Component component) {this.component = component;}</tspan>
            <tspan y="163" x="9" style="white-space:pre">        @Override</tspan>
            <tspan y="178" x="9" style="white-space:pre">        protected Object </tspan>
            <tspan class="st4" style="white-space:pre">clone</tspan>
            <tspan style="white-space:pre">() throws CloneNotSupportedException {</tspan>
            <tspan y="195" x="9" style="white-space:pre">            // 浅拷贝，就是我们现在的一个实现</tspan>
            <tspan y="212" x="9" style="white-space:pre">            // 就是仅仅简单的对当前所有的变量进行一个拷贝</tspan>
            <tspan y="227" x="9" style="white-space:pre">           // return new </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan style="white-space:pre">(getName(), getComponent());</tspan>
            <tspan y="259" x="9" style="white-space:pre">            // 深拷贝，递归对自己引用的对象也进行拷贝</tspan>
            <tspan y="274" x="9" style="white-space:pre">            return new </tspan>
            <tspan class="st4" style="white-space:pre">Product</tspan>
            <tspan style="white-space:pre">(getName(), (Component) getComponent().</tspan>
            <tspan class="st4" style="white-space:pre">clone</tspan>
            <tspan style="white-space:pre">());</tspan>
            <tspan y="289" x="9" style="white-space:pre">        }</tspan>
            <tspan y="304" x="9" style="white-space:pre">    }</tspan>
        </text>
    </g>
    <g ed:width="562.5" ed:height="56" ed:layout="map" id="616" transform="matrix(1,0,0,1,1375,1142)" ed:topictype="floating">
        <path fill="#ffffff" d="M4,0L558.5,0C561.2,0,562.5,1.3,562.5,4L562.5,52C562.5,54.7,561.2,56,558.5,56L4,56C1.3,56,0,54.7,0,52L0,4C0,1.3,1.3,0,4,0z" stroke="#eb6d71" stroke-linejoin="round"/>
        <text class="st15">
            <tspan y="24" x="18" style="white-space:pre">创建型模式</tspan>
            <tspan class="st16" style="white-space:pre">主要解决对象的创建问题，封装复杂的创建过程，解耦对象的创建代</tspan>
            <tspan y="45" x="18" class="st16" style="white-space:pre">码和使用代码。</tspan>
        </text>
    </g>
    <g ed:width="218.578" ed:height="19" ed:layout="rightmap" id="619" transform="matrix(1,0,0,1,1547,1237)" ed:parentid="616">
        <path fill="#ffffff" d="M0,0L218.6,0L218.6,19L0,19L0,0z"/>
        <text class="st7">
            <tspan y="15" x="9" class="st6" style="white-space:pre">1、</tspan>
            <tspan style="white-space:pre">单例模式</tspan>
            <tspan class="st6" style="white-space:pre">用来创建全局唯一的对象</tspan>
        </text>
    </g>
    <g ed:width="515" ed:height="36" ed:layout="rightmap" id="621" transform="matrix(1,0,0,1,1399,1295)" ed:parentid="616">
        <path fill="#ffffff" d="M0,0L515,0L515,36L0,36L0,0z"/>
        <text class="st7">
            <tspan y="15" x="9" class="st6" style="white-space:pre">2、</tspan>
            <tspan style="white-space:pre">工厂模式</tspan>
            <tspan class="st6" style="white-space:pre">用来创建不同但是相关类型的对象（继承同一父类或者接口的一组子类），由给</tspan>
            <tspan y="32" x="9" class="st6" style="white-space:pre">定的参数来决定创建哪种类型的对象</tspan>
        </text>
    </g>
    <g ed:width="515" ed:height="36" ed:layout="rightmap" id="623" transform="matrix(1,0,0,1,1399,1370)" ed:parentid="616">
        <path fill="#ffffff" d="M0,0L515,0L515,36L0,36L0,0z"/>
        <text class="st7">
            <tspan y="15" x="9" class="st6" style="white-space:pre">3、</tspan>
            <tspan style="white-space:pre">建造者模式</tspan>
            <tspan class="st6" style="white-space:pre">是用来创建复杂对象，可以通过设置不同的可选参数，“定制化”地创建不同的对</tspan>
            <tspan y="32" x="9" class="st6" style="white-space:pre">象</tspan>
        </text>
    </g>
    <g ed:width="515" ed:height="36" ed:layout="rightmap" id="625" transform="matrix(1,0,0,1,1399,1445)" ed:parentid="616">
        <path fill="#ffffff" d="M0,0L515,0L515,36L0,36L0,0z"/>
        <text class="st7">
            <tspan y="15" x="9" class="st6" style="white-space:pre">4、</tspan>
            <tspan style="white-space:pre">原型模式</tspan>
            <tspan class="st6" style="white-space:pre">针对创建成本比较大的对象，利用对已有对象进行复制的方式进行创建，以达到</tspan>
            <tspan y="32" x="9" class="st6" style="white-space:pre">节省创建时间的目的。</tspan>
        </text>
    </g>
    <symbol id="plus">
        <path fill="url(#lg1)" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6z"/>
        <path fill="none" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6zM3,6L9,6M6,3L6,9" stroke-width="0.7" stroke="#46a000"/>
    </symbol>
    <symbol id="minus">
        <path fill="url(#lg1)" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6z"/>
        <path fill="none" d="M11,6C11,8.8,8.8,11,6,11C3.2,11,1,8.8,1,6C1,3.2,3.2,1,6,1C8.8,1,11,3.2,11,6zM3,6L9,6" stroke-width="0.7" stroke="#46a000"/>
    </symbol>
    <g transform="translate(1813,2056)" ed:togtopicid="101">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1999,1570)" ed:togtopicid="102">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2152,533)" ed:togtopicid="104">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1343,1610)" ed:togtopicid="107">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2014,3179)" ed:togtopicid="109">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1343,3667)" ed:togtopicid="111">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2152,966)" ed:togtopicid="157">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2245,614)" ed:togtopicid="167">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2252,752)" ed:togtopicid="169">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2252,927)" ed:togtopicid="175">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2264,1123)" ed:togtopicid="187">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2276,1300)" ed:togtopicid="191">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2145,1577)" ed:togtopicid="195">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2370,1430)" ed:togtopicid="197">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2362,1509)" ed:togtopicid="205">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2350,1558)" ed:togtopicid="209">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2362,1629)" ed:togtopicid="215">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2362,1727)" ed:togtopicid="221">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2510,1741)" ed:togtopicid="225">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2742,1741)" ed:togtopicid="229">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2152,1822)" ed:togtopicid="236">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2293,1795)" ed:togtopicid="240">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2212,2013)" ed:togtopicid="248">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2317,2018)" ed:togtopicid="252">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2317,1934)" ed:togtopicid="254">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2365,2098)" ed:togtopicid="258">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2195,2412)" ed:togtopicid="268">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1112,121)" ed:togtopicid="278">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(912,493)" ed:togtopicid="280">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(860,1023)" ed:togtopicid="282">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1158,2304)" ed:togtopicid="292">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(965,1600)" ed:togtopicid="294">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(949,2469)" ed:togtopicid="296">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(949,1435)" ed:togtopicid="298">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(872,1492)" ed:togtopicid="300">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(872,1541)" ed:togtopicid="302">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(824,1649)" ed:togtopicid="304">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1142,1345)" ed:togtopicid="312">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1049,1305)" ed:togtopicid="314">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1049,1332)" ed:togtopicid="316">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1037,1359)" ed:togtopicid="318">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1037,1386)" ed:togtopicid="320">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(769,1555)" ed:togtopicid="338">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(745,1595)" ed:togtopicid="342">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(600,1582)" ed:togtopicid="344">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(599,1609)" ed:togtopicid="348">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(695,1649)" ed:togtopicid="352">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(564,1636)" ed:togtopicid="354">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(563,1663)" ed:togtopicid="356">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(607,1690)" ed:togtopicid="362">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(568,1717)" ed:togtopicid="366">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2191,2825)" ed:togtopicid="395">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2179,3556)" ed:togtopicid="397">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2484,2838)" ed:togtopicid="401">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(3051,2776)" ed:togtopicid="403">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2838,2860)" ed:togtopicid="407">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(3063,2855)" ed:togtopicid="413">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(3063,2882)" ed:togtopicid="417">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2227,3201)" ed:togtopicid="423">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2284,3507)" ed:togtopicid="435">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(2272,3561)" ed:togtopicid="437">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1178,3284)" ed:togtopicid="450">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1094,3463)" ed:togtopicid="452">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(968,3306)" ed:togtopicid="456">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1013,3373)" ed:togtopicid="462">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1013,3476)" ed:togtopicid="464">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(896,3476)" ed:togtopicid="474">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1250,3846)" ed:togtopicid="488">
        <use xlink:href="#minus"/>
    </g>
    <g transform="translate(1650,1199)" ed:togtopicid="616">
        <use xlink:href="#minus"/>
    </g>
</svg>
</div>
        <div id="copyright">Created With  <a href="https://www.edrawsoft.com/" target="_blank" title="edrawsoft">MindMaster</a></div>
      </div>
    </div>
    <script>eval(atob('dmFyIG11YT13aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDsNCnZhciB1YT0obXVhLmluZGV4T2YoJ3J2OjExJykrbXVhLmluZGV4T2YoJ01TSUUnKSk+PTA7DQpkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3ZnLWNvbnRhaW5lcicpLm9uY29udGV4dG1lbnUgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOw0KfQ0KZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N2Zy1jb250YWluZXInKS5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChldmVudCkgew0KICAgIGlmKGV2ZW50LndoaWNoID09Myl7DQogICAgICAgIHRoaXMuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInOw0KICAgICAgICB0aGlzLm9ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKGV2KSB7DQogICAgICAgICAgICB0aGlzLnNjcm9sbEJ5KC0oZXYubW92ZW1lbnRYKSwgMCk7DQogICAgICAgICAgICB3aW5kb3cuc2Nyb2xsQnkoMCwtKGV2Lm1vdmVtZW50WSkpDQogICAgICAgIH0NCiAgICAgICAgdGhpcy5vbm1vdXNldXAgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnN0eWxlLmN1cnNvciA9ICBudWxsOw0KICAgICAgICAgICAgdGhpcy5vbm1vdXNldXAgPSBudWxsOw0KICAgICAgICAgICAgdGhpcy5vbm1vdXNlbW92ZSA9IG51bGw7DQogICAgICAgIH0NCiAgICB9DQp9DQpOdW1iZXIucHJvdG90eXBlLnRvc3VpdHN2Zz1mdW5jdGlvbiAoKSB7DQogICAgdmFyIG51bT10aGlzLnZhbHVlT2YoKTsNCiAgICBpZihudW0lMT09PTApew0KICAgICAgICByZXR1cm4gbnVtKzAuNQ0KICAgIH1lbHNlIHJldHVybiBudW07DQp9Ow0KTnVtYmVyLnByb3RvdHlwZS5wbHVzej1mdW5jdGlvbigpIHsNCiAgICB2YXIgbnVtPXRoaXMudmFsdWVPZigpOw0KICAgIHJldHVybiBudW08MTA/JzAnK251bTpudW07DQp9Ow0KZnVuY3Rpb24gcGFyc2VEYXRlKG51bSkgew0KICAgIHZhciBkYXRlID0gbmV3IERhdGUobnVtKTsNCiAgICB2YXIgWSA9IGRhdGUuZ2V0RnVsbFllYXIoKSArICctJzsNCiAgICB2YXIgTSA9IChkYXRlLmdldE1vbnRoKCkrMSkucGx1c3ooKSArICctJzsNCiAgICB2YXIgRCA9IGRhdGUuZ2V0RGF0ZSgpLnBsdXN6KCkgKyAnICc7DQogICAgdmFyIGggPSBkYXRlLmdldEhvdXJzKCkucGx1c3ooKSArICc6JzsNCiAgICB2YXIgbW0gPSBkYXRlLmdldE1pbnV0ZXMoKS5wbHVzeigpICsgJzonOw0KICAgIHZhciBzID0gZGF0ZS5nZXRTZWNvbmRzKCkucGx1c3ooKTsNCiAgICByZXR1cm4gWStNK0QraCttbStzOw0KfQ0KLy8tLXByZWRlZmluZWQNCi8vY29tbWVudC0tDQp2YXIgY29tbWVudHM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZz5nW2VkXFw6Y29tbWVudF0nKTsNCmZ1bmN0aW9uIGdldGN3aChwb3B1cCkgew0KICAgIGRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3N2ZycpWzBdLmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICB2YXIgdz1wb3B1cC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDsNCiAgICB2YXIgaD1wb3B1cC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7DQogICAgcmV0dXJuIFt3LGhdDQp9DQpmb3IodmFyIGk9MDtpPGNvbW1lbnRzLmxlbmd0aDtpKyspew0KICAgIHZhciBwb3B1cD1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywnZycpOw0KICAgIHZhciBwb3B1cFI9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgdmFyIGhvdmVyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgdmFyIG9saW5lPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCdmaWxsJywnI2NkY2RmZicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgneCcsJzAnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3knLCcwJyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCcxNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywnMC42Jyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLGNvbW1lbnRzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykpOw0KICAgIGhvdmVyLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIGNvbW1lbnRzW2ldLmFwcGVuZENoaWxkKGhvdmVyKTsNCiAgICB2YXIgYT1KU09OLnBhcnNlKGNvbW1lbnRzW2ldLmdldEF0dHJpYnV0ZSgnZWQ6Y29tbWVudCcpKTsNCiAgICB2YXIgaGVpZ2h0PTA7DQogICAgdmFyIGNhcnI9W107DQogICAgZm9yKHZhciBqPTA7ajxhLmxlbmd0aDtqKyspew0KICAgICAgICB2YXIgc3RhbXA9TnVtYmVyKGFbal0uRGF0ZSkqMTAwMDsNCiAgICAgICAgdmFyIHRpbWU9cGFyc2VEYXRlKHN0YW1wKTsNCiAgICAgICAgdmFyIG5hbWU9YVtqXS5OYW1lOw0KICAgICAgICB2YXIgbWVzc2FnZT1hW2pdLk1lc3NhZ2U7DQogICAgICAgIHZhciBtZXNzYWdlQXJyPW1lc3NhZ2Uuc3BsaXQoL1xuLyk7DQogICAgICAgIHZhciBvPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdnJyk7DQogICAgICAgIHZhciBuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciBtPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIG4uc2V0QXR0cmlidXRlKCd4Jyw1KTsNCiAgICAgICAgbi5zZXRBdHRyaWJ1dGUoJ3knLDEyKTsNCiAgICAgICAgbi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCcjMDA2ZWZmJyk7DQogICAgICAgIG4udGV4dENvbnRlbnQ9bmFtZSsnOiAnOw0KICAgICAgICBuLnNldEF0dHJpYnV0ZSgnZm9udC1zaXplJywnMTInKTsNCiAgICAgICAgdC5zZXRBdHRyaWJ1dGUoJ3gnLDIwMCk7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCd5JywxMik7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCdmaWxsJywnIzk2OTY5NicpOw0KICAgICAgICB0LnRleHRDb250ZW50PXRpbWU7DQogICAgICAgIHQuc2V0QXR0cmlidXRlKCdmb250LXNpemUnLCcxMCcpOw0KICAgICAgICBtLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDIwLDI3KScpOw0KICAgICAgICBtLnNldEF0dHJpYnV0ZSgnZm9udC1zaXplJywnMTInKTsNCiAgICAgICAgZm9yKHZhciBrPTA7azxtZXNzYWdlQXJyLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgdmFyIHRzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0c3BhbicpOw0KICAgICAgICAgICAgdHMuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgICAgICAgICAgdHMuc2V0QXR0cmlidXRlKCd5JyxrKjE2KTsNCiAgICAgICAgICAgIHRzLnRleHRDb250ZW50PW1lc3NhZ2VBcnJba107DQogICAgICAgICAgICBtLmFwcGVuZENoaWxkKHRzKTsNCiAgICAgICAgfQ0KICAgICAgICBvLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDAsJytoZWlnaHQrJyknKTsNCiAgICAgICAgby5hcHBlbmRDaGlsZChuKTsNCiAgICAgICAgby5hcHBlbmRDaGlsZCh0KTsNCiAgICAgICAgby5hcHBlbmRDaGlsZChtKTsNCiAgICAgICAgY2Fyci5wdXNoKG8pOw0KICAgICAgICBwb3B1cC5hcHBlbmRDaGlsZChvKTsNCiAgICAgICAgaGVpZ2h0PShtZXNzYWdlQXJyLmxlbmd0aCsxKSoxNitoZWlnaHQ7DQogICAgfQ0KICAgIHZhciB3YXJyPWdldGN3aChwb3B1cCk7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgIG9saW5lLnNldEF0dHJpYnV0ZSgneScsJzAnKTsNCiAgICB2YXIgb3c9d2FyclswXSsxMC41Ow0KICAgIHZhciBvaD13YXJyWzFdKzM7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCd3aWR0aCcsb3cpOw0KICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvaCk7DQogICAgb2xpbmUuc2V0QXR0cmlidXRlKCdmaWxsJywnd2hpdGUnKTsNCiAgICBvbGluZS5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsJyM2NTY1NjUnKTsNCiAgICBwb3B1cC5hcHBlbmRDaGlsZChvbGluZSk7DQogICAgdmFyIGw9Y2Fyci5sZW5ndGg7DQogICAgd2hpbGUobC0tKXsNCiAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQoY2FycltsXSk7DQogICAgfQ0KICAgIHBvcHVwLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgfTsNCiAgICBwb3B1cC5vbm1vdXNlb3V0PWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnOw0KICAgIH07DQogICAgdmFyIGNzPWNvbW1lbnRzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICB2YXIgcHM9Y29tbWVudHNbaV0ucGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpOw0KICAgIGlmKHBzLnN1YnN0cigwLDIpID09ICd0cicpew0KICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgdmFyIHg9cGFyc2VGbG9hdChjc1swXSkrcGFyc2VGbG9hdChwcHNbMF0pOw0KICAgICAgICB2YXIgeT1wYXJzZUZsb2F0KHBwc1sxXSk7DQogICAgICAgIHg9eC50b3N1aXRzdmcoKTsNCiAgICAgICAgeT15LnRvc3VpdHN2ZygpOw0KICAgICAgICB2YXIgdHJzdHIgPSAndHJhbnNsYXRlKCcreCsnLCcreSsnKSc7DQogICAgfQ0KICAgIGVsc2UgaWYocHMuc3Vic3RyKDAsMikgPT0gJ21hJyl7DQogICAgICAgIHZhciBwcHMgPSBwcy5tYXRjaCgvKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVtcLCBdKFwtP1xkKyhcLlxkKyk/KVwpJC8pOw0KICAgICAgICB2YXIgbWFBcnIgPSBbcGFyc2VGbG9hdChwcHNbMV0pLHBhcnNlRmxvYXQocHBzWzNdKSxwYXJzZUZsb2F0KHBwc1s1XSkscGFyc2VGbG9hdChwcHNbN10pLHBhcnNlRmxvYXQocHBzWzldKSxwYXJzZUZsb2F0KHBwc1sxMV0pXTsNCiAgICAgICAgaWYobWFBcnJbMV0gPT0gMCl7DQogICAgICAgICAgICB2YXIgeCA9IHBhcnNlRmxvYXQoY3NbMF0pOw0KICAgICAgICAgICAgdmFyIHk9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgdmFyIHgxID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgeTE9eTEudG9zdWl0c3ZnKCk7DQogICAgICAgICAgICB2YXIgdHJzdHIgPSAgJ3RyYW5zbGF0ZSgnK3gxKycsJyt5MSsnKSc7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKSsxNjsNCiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VGbG9hdChjc1sxXSkrMTY7DQogICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgeCA9IHBhcnNlRmxvYXQoY3NbMF0pKzE2Ow0KICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgdmFyIHgyID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTIgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBmeSA9IHkxPnkyP3kxLnRvc3VpdHN2ZygpOiB5Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBvZmZ5ID0gTWF0aC5hYnMoeTEteTIpOw0KICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvZmZ5LnRvU3RyaW5nKCkpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpOw0KICAgICAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQocG9wdXBSKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBwb3B1cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsdHJzdHIpOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnY29tbWVudCcsJycpOw0KICAgIHBvcHVwLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnZWQ6Y29tbWVudGlkJyxjb21tZW50c1tpXS5wYXJlbnROb2RlLmlkKTsNCiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc3ZnLWNvbnRhaW5lciA+IHN2ZycpLmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICBjb21tZW50c1tpXS5vbm1vdXNlb3Zlcj1mdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBjb21tZW50aWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDpjb21tZW50aWQ9JyIrY29tbWVudGlkKyInXVtjb21tZW50XSIpLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICB9Ow0KICAgIGNvbW1lbnRzW2ldLm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgY29tbWVudGlkPXRoaXMucGFyZW50Tm9kZS5pZDsNCi8vICAgICAgICB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlQWxsUmFuZ2VzKCk7DQogICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6Y29tbWVudGlkPSciK2NvbW1lbnRpZCsiJ11bY29tbWVudF0iKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9DQp9DQovLy0tY29tbWVudA0KLy9ub3RlLS0NCmlmKCF1YSl7DQogICAgdmFyIG5vdGVzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2c+Z1tlZFxcOm5vdGVdJyk7DQogICAgZnVuY3Rpb24gZ2V0d2gocyxwKSB7DQogICAgICAgIHZhciBtYWlucD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsNCiAgICAgICAgbWFpbnAuc3R5bGUuY3NzVGV4dD1zOw0KICAgICAgICBtYWlucC5zdHlsZS5kaXNwbGF5PSdpbmxpbmUtYmxvY2snOw0KCQltYWlucC5zdHlsZS5tYXhXaWR0aCA9ICc0MDBweCc7DQoJCW1haW5wLnN0eWxlLndvcmRCcmVhayA9ICdicmVhay1hbGwnOw0KICAgICAgICBtYWlucC5pbm5lckhUTUw9cDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChtYWlucCk7DQogICAgICAgIHZhciB3PW1haW5wLmNsaWVudFdpZHRoOw0KICAgICAgICB2YXIgaD1tYWlucC5jbGllbnRIZWlnaHQ7DQogICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobWFpbnApOw0KICAgICAgICByZXR1cm4gW3csaF0NCiAgICB9DQogICAgZm9yKHZhciBpPTA7aTxub3Rlcy5sZW5ndGg7aSsrKXsNCiAgICAgICAgdmFyIGE9bm90ZXNbaV0uZ2V0QXR0cmlidXRlKCdlZDpub3RlJyk7DQoJCXZhciBub3RlTG9jayA9IG5vdGVzW2ldLmdldEF0dHJpYnV0ZSgnZWQ6bm90ZWxvY2snKTsNCiAgICAgICAgaWYobm90ZUxvY2sgPT0gJ3RydWUnKXsNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIHZhciBtYWlucD1hLm1hdGNoKC88Ym9keVtePl0qPiguKik8XC9ib2R5Pi8pWzFdOw0KICAgICAgICB2YXIgbWFpbnM9YS5tYXRjaCgvc3R5bGU9IiguKj8pIi8pWzFdOw0KICAgICAgICB2YXIgb3V0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdnJyk7DQogICAgICAgIHZhciBvbGluZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgICAgICB2YXIgcG9wdXA9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ2ZvcmVpZ25PYmplY3QnKTsNCiAgICAgICAgdmFyIHBvcHVwUj0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ3JlY3QnKTsNCiAgICAgICAgdmFyIGhvdmVyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNjZGNkZmYnKTsNCiAgICAgICAgaG92ZXIuc2V0QXR0cmlidXRlKCd4JywnMCcpOw0KICAgICAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3knLCcwJyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywnMTYnKTsNCiAgICAgICAgaG92ZXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsJzE2Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywnMC42Jyk7DQogICAgICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyxub3Rlc1tpXS5xdWVyeVNlbGVjdG9yKCd1c2UnKS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpKTsNCiAgICAgICAgaG92ZXIuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIG5vdGVzW2ldLmFwcGVuZENoaWxkKGhvdmVyKTsNCiAgICAgICAgcG9wdXAuc3R5bGUuY3NzVGV4dD1tYWluczsNCiAgICAgICAgcG9wdXAuaW5uZXJIVE1MPW1haW5wOw0KICAgICAgICB2YXIgd2g9Z2V0d2gobWFpbnMsbWFpbnApOw0KICAgICAgICBwb3B1cC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3aFswXSk7DQogICAgICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx3aFsxXSk7DQogICAgICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywndHJhbnNsYXRlKDgsNCknKTsNCgkJcG9wdXAuc3R5bGUud29yZEJyZWFrID0gJ2JyZWFrLWFsbCc7DQogICAgICAgIHBvcHVwLnN0eWxlLnRleHRBbGlnbj0nbGVmdCc7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgneCcsJzAnKTsNCiAgICAgICAgb2xpbmUuc2V0QXR0cmlidXRlKCd5JywnMCcpOw0KICAgICAgICBvbGluZS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJyx3aFswXSsxNik7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnaGVpZ2h0Jyx3aFsxXSs4KTsNCiAgICAgICAgb2xpbmUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCcjYTI3YTAwJyk7DQogICAgICAgIG9saW5lLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNmZmU3OWQnKTsNCiAgICAgICAgb3V0LmFwcGVuZENoaWxkKG9saW5lKTsNCiAgICAgICAgb3V0LmFwcGVuZENoaWxkKHBvcHVwKTsNCiAgICAgICAgb3V0LnNldEF0dHJpYnV0ZSgnbm90ZScsJycpOw0KICAgICAgICBvdXQuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIG91dC5zZXRBdHRyaWJ1dGUoJ2VkOm5vdGVpZCcsbm90ZXNbaV0ucGFyZW50Tm9kZS5pZCk7DQogICAgICAgIG91dC5vbm1vdXNlb3Zlcj1mdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICAgICAgfTsNCiAgICAgICAgb3V0Lm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KLy8gICAgICAgIHdpbmRvdy5nZXRTZWxlY3Rpb24gPyB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkucmVtb3ZlUmFuZ2Uod2luZG93LmdldFNlbGVjdGlvbigpLnJlKTpkb2N1bWVudC5zZWxlY3Rpb24uZW1wdHkoKTsNCg0KICAgICAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICAgICAgfTsNCiAgICAgICAgdmFyIGNzPW5vdGVzW2ldLnF1ZXJ5U2VsZWN0b3IoJ3VzZScpLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJykubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgdmFyIHBzPW5vdGVzW2ldLnBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nKTsNCiAgICAgICAgaWYocHMuc3Vic3RyKDAsMikgPT0gJ3RyJyl7DQogICAgICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goL1woKFxTKnxcUypcc1xTKilcKS8pWzFdLnNwbGl0KC8gfCwvKTsNCiAgICAgICAgICAgIHZhciB4PXBhcnNlRmxvYXQoY3NbMF0pK3BhcnNlRmxvYXQocHBzWzBdKTsNCiAgICAgICAgICAgIHZhciB5PXBhcnNlRmxvYXQocHBzWzFdKTsNCiAgICAgICAgICAgIHg9eC50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHk9eS50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciB0cnN0ciA9ICd0cmFuc2xhdGUoJyt4KycsJyt5KycpJzsNCiAgICAgICAgfWVsc2UgaWYocHMuc3Vic3RyKDAsMikgPT0gJ21hJyl7DQogICAgICAgICAgICB2YXIgcHBzID0gcHMubWF0Y2goLyhcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylbXCwgXShcLT9cZCsoXC5cZCspPylcKSQvKTsNCiAgICAgICAgICAgIHZhciBtYUFyciA9IFtwYXJzZUZsb2F0KHBwc1sxXSkscGFyc2VGbG9hdChwcHNbM10pLHBhcnNlRmxvYXQocHBzWzVdKSxwYXJzZUZsb2F0KHBwc1s3XSkscGFyc2VGbG9hdChwcHNbOV0pLHBhcnNlRmxvYXQocHBzWzExXSldOw0KICAgICAgICAgICAgaWYobWFBcnJbMV0gPT0gMCl7DQogICAgICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKTsNCiAgICAgICAgICAgICAgICB2YXIgeSA9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgICAgIHZhciB4MSA9IHggKiBtYUFyclswXSArIHkgKiBtYUFyclsyXSArIG1hQXJyWzRdOw0KICAgICAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgICAgIHkxPXkxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgICAgIHZhciB0cnN0ciA9ICAndHJhbnNsYXRlKCcreDErJywnK3kxKycpJzsNCiAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgIHZhciB4ID0gcGFyc2VGbG9hdChjc1swXSkrMTY7DQogICAgICAgICAgICAgICAgdmFyIHkgPSBwYXJzZUZsb2F0KGNzWzFdKSsxNjsNCiAgICAgICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgICAgICB4ID0gcGFyc2VGbG9hdChjc1swXSkrMTY7DQogICAgICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgICAgIHZhciB4MiA9IHggKiBtYUFyclswXSArIHkgKiBtYUFyclsyXSArIG1hQXJyWzRdOw0KICAgICAgICAgICAgICAgIHZhciB5MiA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgICAgICB2YXIgZnkgPSB5MT55Mj95MS50b3N1aXRzdmcoKTogeTIudG9zdWl0c3ZnKCk7DQoJCQkJdmFyIG9mZnkgPSBNYXRoLmFicyh5MS15Mik7CQkJCQkJCQkJCSAgDQogICAgICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsb2ZmeS50b1N0cmluZygpKTsNCiAgICAgICAgICAgICAgICBwb3B1cFIuc2V0QXR0cmlidXRlKCd3aWR0aCcsJzE2Jyk7DQogICAgICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgICAgICBwb3B1cFIuc2V0QXR0cmlidXRlKCdmaWxsJywndHJhbnNwYXJlbnQnKTsNCiAgICAgICAgICAgICAgICBwb3B1cC5hcHBlbmRDaGlsZChwb3B1cFIpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIG91dC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsdHJzdHIpOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc3ZnLWNvbnRhaW5lciA+IHN2ZycpLmFwcGVuZENoaWxkKG91dCk7DQogICAgICAgIG5vdGVzW2ldLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBub3RlaWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICAgICAgdGhpcy5xdWVyeVNlbGVjdG9yKCdyZWN0Jykuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOm5vdGVpZD0nIitub3RlaWQrIiddW25vdGVdIikuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICB9Ow0KICAgICAgICBub3Rlc1tpXS5vbm1vdXNlb3V0PWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHZhciBub3RlaWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KLy8gICAgICAgIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5yZW1vdmVBbGxSYW5nZXMoKTsNCiAgICAgICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOm5vdGVpZD0nIitub3RlaWQrIiddW25vdGVdIikuc3R5bGUuZGlzcGxheT0nbm9uZSc7DQogICAgICAgIH0NCiAgICB9DQp9ZWxzZXsNCiAgICBjb25zb2xlLmxvZygn5oqx5q2J77yMSUXmtY/op4jlmajkuI3mlK/mjIFub3Rl6Kej5p6Q77yM6K+35L2/55So5YW25LuW5YaF5qC45rWP6KeI5Zmo44CC6LCi6LCi77yBJykNCn0NCi8vLS1ub3RlDQovL2h5cGVybGluay0tDQp2YXIgbGlua3M9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZz5nW2VkXFw6aHlwZXJsaW5rXScpOw0KZnVuY3Rpb24gZ2V0bWF4bGVuKGFycixicnIpIHsNCiAgICB2YXIgbD0wOw0KICAgIHZhciBsbD0wOw0KICAgIGZvcih2YXIgaj0wO2o8YXJyLmxlbmd0aDtqKyspew0KICAgICAgICB2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywndGV4dCcpOw0KICAgICAgICBpZighaXNOYU4obGlua2FycltqXSkpew0KICAgICAgICAgICAgZS50ZXh0Q29udGVudD0nUGFnZS0nK2FycltqXTsNCiAgICAgICAgfWVsc2V7DQogICAgICAgICAgICBlLnRleHRDb250ZW50PWFycltqXTsNCiAgICAgICAgfQ0KICAgICAgICBlLnN0eWxlLmZvbnRTaXplPScxMnB4JzsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0uYXBwZW5kQ2hpbGQoZSk7DQogICAgICAgIHZhciBldz1lLmdldEJCb3goKS53aWR0aDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0ucmVtb3ZlQ2hpbGQoZSk7DQogICAgICAgIHZhciBoPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIGgudGV4dENvbnRlbnQ9YnJyW2pdOw0KICAgICAgICBoLnN0eWxlLmZvbnRTaXplPScxMnB4JzsNCiAgICAgICAgaC5zdHlsZS5mb250V2VpZ2h0PSdib2xkJzsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0uYXBwZW5kQ2hpbGQoaCk7DQogICAgICAgIHZhciBodz1oLmdldEJCb3goKS53aWR0aDsNCiAgICAgICAgZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3ZnJylbMF0ucmVtb3ZlQ2hpbGQoaCk7DQogICAgICAgIGw9ZXc+aHc/ZXc6aHc7DQogICAgICAgIGxsPWw+bGw/bDpsbDsNCiAgICB9DQogICAgcmV0dXJuIGxsOw0KfQ0KZm9yKHZhciBpPTA7aTxsaW5rcy5sZW5ndGg7aSsrKXsNCiAgICB2YXIgcG9wdXA9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsJ2cnKTsNCiAgICB2YXIgcG9wdXBSPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgIHZhciBob3Zlcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJywncmVjdCcpOw0KICAgIHZhciBkZXNjYXJyPVtdOw0KICAgIHZhciBsaW5rYXJyPVtdOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnZmlsbCcsJyNjZGNkZmYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3gnLCcwJyk7DQogICAgaG92ZXIuc2V0QXR0cmlidXRlKCd5JywnMCcpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywnMTYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywnMTYnKTsNCiAgICBob3Zlci5zZXRBdHRyaWJ1dGUoJ2ZpbGwtb3BhY2l0eScsJzAuNicpOw0KICAgIGhvdmVyLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyxsaW5rc1tpXS5xdWVyeVNlbGVjdG9yKCd1c2UnKS5nZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScpKTsNCiAgICBob3Zlci5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICBsaW5rc1tpXS5hcHBlbmRDaGlsZChob3Zlcik7DQogICAgLy8gY29uc29sZS5sb2cobGlua3NbaV0uZ2V0QXR0cmlidXRlKCdlZDpoeXBlcmxpbmsnKSk7DQogICAgdmFyIGE9SlNPTi5wYXJzZShsaW5rc1tpXS5nZXRBdHRyaWJ1dGUoJ2VkOmh5cGVybGluaycpKTsNCiAgICB2YXIgY3M9bGlua3NbaV0ucXVlcnlTZWxlY3RvcigndXNlJykuZ2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nKS5tYXRjaCgvXCgoXFMqfFxTKlxzXFMqKVwpLylbMV0uc3BsaXQoLyB8LC8pOw0KICAgIHZhciBwcz1saW5rc1tpXS5wYXJlbnROb2RlLmdldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyk7DQogICAgaWYocHMuc3Vic3RyKDAsMikgPT0gJ3RyJyl7DQogICAgICAgIHZhciBwcHMgPSBwcy5tYXRjaCgvXCgoXFMqfFxTKlxzXFMqKVwpLylbMV0uc3BsaXQoLyB8LC8pOw0KICAgICAgICB2YXIgeD1wYXJzZUZsb2F0KGNzWzBdKStwYXJzZUZsb2F0KHBwc1swXSk7DQogICAgICAgIHZhciB5PXBhcnNlRmxvYXQocHBzWzFdKTsNCiAgICAgICAgeD14LnRvc3VpdHN2ZygpOw0KICAgICAgICB5PXkudG9zdWl0c3ZnKCk7DQogICAgICAgIHZhciB0cnN0ciA9ICd0cmFuc2xhdGUoJyt4KycsJyt5KycpJzsNCiAgICB9ZWxzZSBpZihwcy5zdWJzdHIoMCwyKSA9PSAnbWEnKXsNCiAgICAgICAgdmFyIHBwcyA9IHBzLm1hdGNoKC8oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pW1wsIF0oXC0/XGQrKFwuXGQrKT8pXCkkLyk7DQogICAgICAgIHZhciBtYUFyciA9IFtwYXJzZUZsb2F0KHBwc1sxXSkscGFyc2VGbG9hdChwcHNbM10pLHBhcnNlRmxvYXQocHBzWzVdKSxwYXJzZUZsb2F0KHBwc1s3XSkscGFyc2VGbG9hdChwcHNbOV0pLHBhcnNlRmxvYXQocHBzWzExXSldOw0KICAgICAgICBpZihtYUFyclsxXSA9PSAwKXsNCiAgICAgICAgICAgIHZhciB4ID0gcGFyc2VGbG9hdChjc1swXSk7DQogICAgICAgICAgICB2YXIgeSA9IHBhcnNlRmxvYXQoY3NbMV0pKzE2Ow0KICAgICAgICAgICAgdmFyIHgxID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTEgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHgxPXgxLnRvc3VpdHN2ZygpOw0KICAgICAgICAgICAgeTE9eTEudG9zdWl0c3ZnKCk7DQogICAgICAgICAgICB2YXIgdHJzdHIgPSAgJ3RyYW5zbGF0ZSgnK3gxKycsJyt5MSsnKSc7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgdmFyIHggPSBwYXJzZUZsb2F0KGNzWzBdKSsxNjsNCiAgICAgICAgICAgIHZhciB5ID0gcGFyc2VGbG9hdChjc1sxXSkrMTY7DQogICAgICAgICAgICB2YXIgeDEgPSB4ICogbWFBcnJbMF0gKyB5ICogbWFBcnJbMl0gKyBtYUFycls0XTsNCiAgICAgICAgICAgIHZhciB5MSA9IHggKiBtYUFyclsxXSArIHkgKiBtYUFyclszXSArIG1hQXJyWzVdOw0KICAgICAgICAgICAgeCA9IHBhcnNlRmxvYXQoY3NbMF0pKzE2Ow0KICAgICAgICAgICAgeSA9IHBhcnNlRmxvYXQoY3NbMV0pOw0KICAgICAgICAgICAgdmFyIHgyID0geCAqIG1hQXJyWzBdICsgeSAqIG1hQXJyWzJdICsgbWFBcnJbNF07DQogICAgICAgICAgICB2YXIgeTIgPSB4ICogbWFBcnJbMV0gKyB5ICogbWFBcnJbM10gKyBtYUFycls1XTsNCiAgICAgICAgICAgIHZhciBmeCA9IHgxPHgyP3gxLnRvc3VpdHN2ZygpOiB4Mi50b3N1aXRzdmcoKTsNCiAgICAgICAgICAgIHZhciBmeSA9IHkxPnkyP3kxLnRvc3VpdHN2ZygpOiB5Mi50b3N1aXRzdmcoKTsNCgkJCXZhciBvZmZ5ID0gTWF0aC5hYnMoeTEteTIpOwkJCQkJCQkJCQkgIA0KICAgICAgICAgICAgdmFyIHRyc3RyID0gICd0cmFuc2xhdGUoJytmeCsnLCcrZnkrJyknOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxvZmZ5LnRvU3RyaW5nKCkpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCcxNicpOw0KICAgICAgICAgICAgcG9wdXBSLnNldEF0dHJpYnV0ZSgneScsKC1vZmZ5KS50b1N0cmluZygpKTsNCiAgICAgICAgICAgIHBvcHVwUi5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCd0cmFuc3BhcmVudCcpOw0KICAgICAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQocG9wdXBSKTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICB2YXIgYWw9YS5sZW5ndGg7DQogICAgZm9yKHZhciBqPTA7ajxhbDtqKyspew0KICAgICAgICBsaW5rYXJyLnB1c2goYVtqXS5saW5rKTsNCiAgICAgICAgZGVzY2Fyci5wdXNoKGFbal0uZGVzYyk7DQogICAgfQ0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJyx0cnN0cik7DQogICAgdmFyIG1heD1nZXRtYXhsZW4obGlua2FycixkZXNjYXJyKTsNCiAgICBmb3IodmFyIGs9MDtrPGFsO2srKyl7DQogICAgICAgIHZhciBjPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdhJyk7DQogICAgICAgIHZhciBkPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCdyZWN0Jyk7DQogICAgICAgIHZhciBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIHZhciBmPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCd0ZXh0Jyk7DQogICAgICAgIGlmKGlzTmFOKGxpbmthcnJba10pKXsNCiAgICAgICAgICAgIGMuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiwgInhsaW5rIiwgImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiKTsNCiAgICAgICAgICAgIGMuc2V0QXR0cmlidXRlTlMoImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiLCAiaHJlZiIsIGxpbmthcnJba10pOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGUoJ3RhcmdldCcsJ19ibGFuaycpOw0KICAgICAgICAgICAgZS50ZXh0Q29udGVudD1saW5rYXJyW2tdOw0KICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgIGUudGV4dENvbnRlbnQ9J1BhZ2UtJytsaW5rYXJyW2tdOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLCAieGxpbmsiLCAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIpOw0KICAgICAgICAgICAgYy5zZXRBdHRyaWJ1dGVOUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIsICJocmVmIiwgIiMiK2xpbmthcnJba10pOw0KICAgICAgICB9DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCd3aWR0aCcsbWF4KzEwKTsNCiAgICAgICAgZC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsJzMzJyk7DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCdzdHJva2UnLCcjOTk5OTk5Jyk7DQogICAgICAgIGQuc2V0QXR0cmlidXRlKCdmaWxsJywnd2hpdGUnKTsNCiAgICAgICAgZC5zZXRBdHRyaWJ1dGUoJ3knLDMzKmspOw0KICAgICAgICBmLnRleHRDb250ZW50PWRlc2NhcnJba107DQogICAgICAgIGYuc3R5bGUuZm9udFNpemU9JzEycHgnOw0KICAgICAgICBmLnN0eWxlLmZvbnRXZWlnaHQ9J2JvbGQnOw0KICAgICAgICBmLnNldEF0dHJpYnV0ZSgneCcsNSk7DQogICAgICAgIGYuc2V0QXR0cmlidXRlKCd5JywzMyprKzEyKTsNCiAgICAgICAgZS5zdHlsZS5mb250U2l6ZT0nMTJweCc7DQogICAgICAgIGUuc2V0QXR0cmlidXRlKCd5JywzMyprKzI4KTsNCiAgICAgICAgZS5zZXRBdHRyaWJ1dGUoJ3gnLDUpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGQpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGYpOw0KICAgICAgICBjLmFwcGVuZENoaWxkKGUpOw0KICAgICAgICBjLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgIHRoaXMucXVlcnlTZWxlY3RvcigncmVjdCcpLnN0eWxlLmZpbGw9JyNlMWUxZmYnDQogICAgICAgIH07DQogICAgICAgIGMub25tb3VzZW91dD1mdW5jdGlvbiAoKSB7DQogICAgICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5maWxsPSd3aGl0ZScNCiAgICAgICAgfTsNCiAgICAgICAgcG9wdXAuYXBwZW5kQ2hpbGQoYyk7DQogICAgfQ0KICAgIHBvcHVwLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIHBvcHVwLnNldEF0dHJpYnV0ZSgnaHlwZXJsaW5rJywnJyk7DQogICAgcG9wdXAuc2V0QXR0cmlidXRlKCdlZDpsaW5raWQnLGxpbmtzW2ldLnBhcmVudE5vZGUuaWQpOw0KICAgIHBvcHVwLm9ubW91c2VvdmVyPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdibG9jayc7DQogICAgfTsNCiAgICBwb3B1cC5vbmNsaWNrPWZ1bmN0aW9uICgpIHsNCiAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9Ow0KICAgIHBvcHVwLm9ubW91c2VvdXQ9ZnVuY3Rpb24gKCkgew0KICAgICAgICB0aGlzLnN0eWxlLmRpc3BsYXk9J25vbmUnOw0KICAgIH07DQogICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N2Zy1jb250YWluZXIgPiBzdmcnKS5hcHBlbmRDaGlsZChwb3B1cCk7DQogICAgbGlua3NbaV0ub25tb3VzZW92ZXI9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgbGlua2lkPXRoaXMucGFyZW50Tm9kZS5pZDsNCiAgICAgICAgdGhpcy5xdWVyeVNlbGVjdG9yKCdyZWN0Jykuc3R5bGUuZGlzcGxheT0nYmxvY2snOw0KICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6bGlua2lkPSciK2xpbmtpZCsiJ11baHlwZXJsaW5rXSIpLnN0eWxlLmRpc3BsYXk9J2Jsb2NrJzsNCiAgICB9DQogICAgbGlua3NbaV0ub25tb3VzZW91dD1mdW5jdGlvbiAoKSB7DQogICAgICAgIHZhciBsaW5raWQ9dGhpcy5wYXJlbnROb2RlLmlkOw0KICAgICAgICB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3JlY3QnKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOmxpbmtpZD0nIitsaW5raWQrIiddW2h5cGVybGlua10iKS5zdHlsZS5kaXNwbGF5PSdub25lJzsNCiAgICB9DQp9DQovLy0taHlwZXJsaW5rDQovL2luaXRpYWxpemUtLQ0KdmFyIHNoYXBlPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2dbZWRcXDp0b2d0b3BpY2lkXScpOw0KdmFyIG1JZD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdnW2VkXFw6dG9waWN0eXBlXScpOw0KdmFyIGRhdGFUcmVlPXt9Ow0KdmFyIGV4dHJhUmVsYT17fTsNCnZhciBjaGVja0lEPScnOw0KZm9yKHZhciBpPTA7aTxtSWQubGVuZ3RoO2krKyl7DQogICAgdmFyIHR5cGU9bUlkW2ldLmdldEF0dHJpYnV0ZSgnZWQ6dG9waWN0eXBlJyk7DQogICAgdmFyIHNpZD1tSWRbaV0uaWQ7DQogICAgaWYodHlwZSE9PSdjYWxsb3V0Jyl7DQogICAgICAgIGluaXQoc2lkLGRhdGFUcmVlKQ0KICAgIH0NCn0NCmZ1bmN0aW9uIGluaXQoaWQsIG9iaikgew0KICAgIHZhciBjaGlsZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6cGFyZW50aWQ9JyIgKyBpZCArICInXTpub3QoW2VkXFw6dG9waWN0eXBlXSkiKTsNCiAgICB2YXIgY2FsbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6cGFyZW50aWQ9JyIgKyBpZCArICInXVtlZFxcOnRvcGljdHlwZV0iKTsNCiAgICB2YXIgc3VtbWFyeSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoInBhdGhbZWRcXDpwYXJlbnRpZCo9JyIgKyBpZCArICInXVtlZFxcOnR5cGU9J3N1bW1hcnknXSIpOw0KICAgIHZhciBib3VuZGFyeT0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgicGF0aFtlZFxcOnBhcmVudGlkKj0nIiArIGlkICsgIiddW2VkXFw6dHlwZT0nYm91bmRhcnknXSIpOw0KICAgIHZhciByZWxhZnJvbT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCJnW2VkXFw6ZnJvbWlkKj0nIiArIGlkICsgIiddW2VkXFw6dHlwZT0ncmVsYXRpb24nXSIpOw0KICAgIHZhciByZWxhdG89ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiZ1tlZFxcOnRvaWQqPSciICsgaWQgKyAiJ11bZWRcXDp0eXBlPSdyZWxhdGlvbiddIik7DQogICAgb2JqWyJtIiArIGlkXSA9IHt9Ow0KICAgIHZhciB0eXBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmdldEF0dHJpYnV0ZSgnZWQ6dG9waWN0eXBlJyk7DQogICAgdmFyIGl3PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOndpZHRoJyk7DQogICAgdmFyIGloPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOmhlaWdodCcpOw0KICAgIGlmICh0eXBlKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0udHlwZSA9IHR5cGU7DQogICAgfQ0KICAgIGlmKGl3JiZpaCl7DQogICAgICAgIG9ialsibSIgKyBpZF0ud2lkdGggPWl3Ow0KICAgICAgICBvYmpbIm0iICsgaWRdLmhlaWdodCA9aWg7DQogICAgfQ0KICAgIGlmIChyZWxhZnJvbS5sZW5ndGggIT09IDApIHsNCiAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhZnJvbSA9IHt9Ow0KICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlbGFmcm9tLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgaW5kZXhpZCA9IHJlbGFmcm9tW2ldLmlkOw0KICAgICAgICAgICAgdmFyIHRvaWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpbmRleGlkKS5nZXRBdHRyaWJ1dGUoJ2VkOnRvaWQnKTsNCiAgICAgICAgICAgIGlmIChleHRyYVJlbGFbaW5kZXhpZF0gPT09IHVuZGVmaW5lZCkgew0KICAgICAgICAgICAgICAgIGV4dHJhUmVsYVtpbmRleGlkXSA9IHsNCiAgICAgICAgICAgICAgICAgICAgaWQ6IGluZGV4aWQsDQogICAgICAgICAgICAgICAgICAgIGZyb21pZDogaWQsDQogICAgICAgICAgICAgICAgICAgIHRvaWQ6IHRvaWQsDQogICAgICAgICAgICAgICAgICAgIGlzQzogZmFsc2UNCiAgICAgICAgICAgICAgICB9Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhZnJvbVtpbmRleGlkXT17fTsNCiAgICAgICAgICAgIG9ialsibSIgKyBpZF0ucmVsYWZyb20uZGlzcGxheT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnPydibG9jayc6J25vbmUnOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChyZWxhdG8ubGVuZ3RoICE9PSAwKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0ucmVsYXRvID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVsYXRvLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgaW5kZXhpZD1yZWxhdG9baV0uaWQ7DQogICAgICAgICAgICB2YXIgZnJvbWlkPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGluZGV4aWQpLmdldEF0dHJpYnV0ZSgnZWQ6ZnJvbWlkJyk7DQogICAgICAgICAgICBpZihleHRyYVJlbGFbaW5kZXhpZF0gPT09IHVuZGVmaW5lZCl7DQogICAgICAgICAgICAgICAgZXh0cmFSZWxhW2luZGV4aWRdPXsNCiAgICAgICAgICAgICAgICAgICAgaWQ6aW5kZXhpZCwNCiAgICAgICAgICAgICAgICAgICAgZnJvbWlkOmZyb21pZCwNCiAgICAgICAgICAgICAgICAgICAgdG9pZDppZCwNCiAgICAgICAgICAgICAgICAgICAgaXNDOmZhbHNlDQogICAgICAgICAgICAgICAgfTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIG9ialsibSIgKyBpZF0ucmVsYXRvW2luZGV4aWRdPXt9Ow0KICAgICAgICAgICAgb2JqWyJtIiArIGlkXS5yZWxhdG8uZGlzcGxheT1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnPydibG9jayc6J25vbmUnOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChjaGlsZHMubGVuZ3RoICE9PSAwKSB7DQogICAgICAgIG9ialsibSIgKyBpZF0uY2hpbGQgPSB7fTsNCiAgICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciICsgaWQgKyAiJ10iKSkgew0KICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOnRvZ3RvcGljaWQ9JyIgKyBpZCArICInXSIpLmNoaWxkTm9kZXNbMF0uZ2V0QXR0cmlidXRlKCd4bGluazpocmVmJykpOw0KICAgICAgICAgICAgdmFyIHRvZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciICsgaWQgKyAiJ10iKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgndXNlJylbMF0uZ2V0QXR0cmlidXRlKCd4bGluazpocmVmJykuc2xpY2UoMSk7DQogICAgICAgICAgICBvYmpbIm0iICsgaWRdLnRvZ3R5cGUgPSB0b2c7DQogICAgICAgIH0NCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIHZhciBjaWQgPSBjaGlsZHNbaV0uaWQ7DQogICAgICAgICAgICBpbml0KGNpZCwgb2JqWyJtIiArIGlkXS5jaGlsZCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKGNhbGxzLmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLmNhbGwgPSB7fTsNCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxscy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgdmFyIGNpZCA9IGNhbGxzW2ldLmlkOw0KICAgICAgICAgICAgaW5pdChjaWQsIG9ialsibSIgKyBpZF0uY2FsbCk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKGJvdW5kYXJ5Lmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLmJvdW5kYXJ5ID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYm91bmRhcnkubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgIHZhciBjaWQgPWJvdW5kYXJ5W2ldLmlkOw0KICAgICAgICAgICAgaW5pdChjaWQsIG9ialsibSIgKyBpZF0uYm91bmRhcnkpOw0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChzdW1tYXJ5Lmxlbmd0aCAhPT0gMCkgew0KICAgICAgICBvYmpbIm0iICsgaWRdLnN1bW1hcnkgPSB7fTsNCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdW1tYXJ5Lmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgY2lkID0gc3VtbWFyeVtpXS5pZDsNCiAgICAgICAgICAgIGluaXQoY2lkLCBvYmpbIm0iICsgaWRdLnN1bW1hcnkpOw0KICAgICAgICB9DQogICAgfQ0KfQ0KLy8tLWluaXRpYWxpemUNCi8vdG9nZ2xlZGlzcGxheS0tDQp2YXIgY2hhaW5BcnI9W107DQpmdW5jdGlvbiBnZXRjaGFpbihpZCl7DQogICAgY2hhaW5BcnIudW5zaGlmdCgnbScraWQpOw0KICAgIHZhciBwYXJlbnQ9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmdldEF0dHJpYnV0ZSgnZWQ6cGFyZW50aWQnKTsNCiAgICBpZighcGFyZW50KXsNCiAgICAgICAgcmV0dXJuOw0KICAgIH0NCglpZihwYXJlbnQubWF0Y2goL1wsLykpew0KICAgICAgICBwYXJlbnQgPSBwYXJlbnQubWF0Y2goL1xkKyg/PVwsKS8pWzBdDQogICAgfQ0KICAgIGdldGNoYWluKHBhcmVudCk7DQp9DQpmdW5jdGlvbiBnZXRvYmooaWQpIHsNCiAgICBjaGFpbkFycj1bXTsNCiAgICBnZXRjaGFpbihpZCk7DQogICAgdmFyIG1haW49Y2hhaW5BcnJbMF07DQogICAgaWYoY2hhaW5BcnIubGVuZ3RoPjEpew0KICAgICAgICB2YXIgb2JqPWRhdGFUcmVlW21haW5dOw0KICAgICAgICAvLyBjb25zb2xlLmxvZyhjaGFpbkFycik7DQogICAgICAgIGZvcih2YXIgaT0xO2k8Y2hhaW5BcnIubGVuZ3RoO2krKykgew0KICAgICAgICAgICAgdmFyIGEgPSBjaGFpbkFycltpXTsNCiAgICAgICAgICAgIGZvcih2YXIgaj0wO2o8T2JqZWN0LmtleXMob2JqKS5sZW5ndGg7aisrKXsNCiAgICAgICAgICAgICAgICB2YXIgY29iaj0gb2JqW09iamVjdC5rZXlzKG9iailbal1dW2FdOw0KICAgICAgICAgICAgICAgIGlmKGNvYmopew0KICAgICAgICAgICAgICAgICAgICBvYmo9Y29iajsNCiAgICAgICAgICAgICAgICAgICAgY29udGludWUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG9iag0KICAgIH1lbHNlew0KICAgICAgICB2YXIgb2JqPWRhdGFUcmVlW21haW5dOw0KICAgICAgICByZXR1cm4gb2JqDQogICAgfQ0KDQp9DQpmb3IodmFyIGk9MDtpPHNoYXBlLmxlbmd0aDtpKyspew0KICAgIHNoYXBlW2ldLm9uY2xpY2s9ZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgaWQ9TnVtYmVyKHRoaXMuZ2V0QXR0cmlidXRlKCdlZDp0b2d0b3BpY2lkJykpOw0KICAgICAgICB2YXIgb2JqPWdldG9iaihpZCk7DQoNCiAgICAgICAgdmFyIHR5cGU9b2JqLnRvZ3R5cGU9PT0nbWludXMnPydwbHVzJzonbWludXMnOw0KICAgICAgICB2YXIgZGlzcGxheT1vYmoudG9ndHlwZT09PSdtaW51cyc/J25vbmUnOidibG9jayc7DQogICAgICAgIHRoaXMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3VzZScpWzBdLnNldEF0dHJpYnV0ZSgneGxpbms6aHJlZicsJyMnK3R5cGUpOw0KICAgICAgICBvYmoudG9ndHlwZT10eXBlOw0KICAgICAgICBjaGVja0lEPW9iajsNCg0KICAgICAgICB1dGQob2JqLGlkLGRpc3BsYXkpOw0KICAgICAgICBleHRyYVJlbGFGaW4oKTsNCiAgICB9DQp9DQpmdW5jdGlvbiB1dGQob2JqLGlkLHNob3csb2MpIHsNCg0KICAgIHZhciBwc2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuc3R5bGUuZGlzcGxheSE9PSAnbm9uZSc/J2Jsb2NrJzonbm9uZSc7DQogICAgaWYgKG9iai5yZWxhZnJvbSl7DQogICAgICAgIGlmKG9iai5yZWxhZnJvbS5kaXNwbGF5IT09IHBzaG93KXsNCiAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMob2JqLnJlbGFmcm9tKTsNCiAgICAgICAgICAgIHJlbGFmcm9tcy5zcGxpY2UocmVsYWZyb21zLmluZGV4T2YoJ2Rpc3BsYXknKSwxKTsNCiAgICAgICAgICAgIGZvcih2YXIgaz0wO2s8cmVsYWZyb21zLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgICAgIHZhciBkPXJlbGFmcm9tc1trXTsNCiAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBvYmoucmVsYWZyb20uZGlzcGxheSA9IHBzaG93Ow0KICAgICAgICB9DQogICAgfQ0KICAgIGlmIChvYmoucmVsYXRvKXsNCiAgICAgICAgaWYob2JqLnJlbGF0by5kaXNwbGF5IT09IHBzaG93KXsNCiAgICAgICAgICAgIHZhciByZWxhdG9zPU9iamVjdC5rZXlzKG9iai5yZWxhdG8pOw0KICAgICAgICAgICAgcmVsYXRvcy5zcGxpY2UocmVsYXRvcy5pbmRleE9mKCdkaXNwbGF5JyksMSk7DQogICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGF0b3MubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgdmFyIGQ9cmVsYXRvc1trXTsNCiAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBvYmoucmVsYXRvLmRpc3BsYXkgPSBwc2hvdzsNCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZihvYmouY2FsbCl7DQogICAgICAgIHZhciBjYWxscz1PYmplY3Qua2V5cyhvYmouY2FsbCk7DQogICAgICAgIGlmKGNoZWNrSUQhPT1vYmopew0KICAgICAgICAgICAgZm9yKHZhciBpPTA7aSA8IGNhbGxzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPWNhbGxzW2ldLnNsaWNlKDEpOw0KICAgICAgICAgICAgICAgIHZhciBiPW9iai5jYWxsW2NhbGxzW2ldXTsNCiAgICAgICAgICAgICAgICB2YXIgYz1iLnRvZ3R5cGU7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYSkuc3R5bGUuZGlzcGxheT1zaG93Ow0KICAgICAgICAgICAgICAgIGlmIChiLnJlbGFmcm9tJiYhYyl7DQogICAgICAgICAgICAgICAgICAgIGlmKGIucmVsYWZyb20uZGlzcGxheSE9PSBzaG93KXsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMoYi5yZWxhZnJvbSk7DQogICAgICAgICAgICAgICAgICAgICAgICByZWxhZnJvbXMuc3BsaWNlKHJlbGFmcm9tcy5pbmRleE9mKCdkaXNwbGF5JyksMSk7DQogICAgICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGFmcm9tcy5sZW5ndGg7aysrKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhZnJvbXNba107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYi5yZWxhZnJvbS5kaXNwbGF5ID0gc2hvdzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoYi5yZWxhdG8mJiFjKXsNCiAgICAgICAgICAgICAgICAgICAgaWYoYi5yZWxhdG8uZGlzcGxheSE9PSBzaG93KXsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhdG9zPU9iamVjdC5rZXlzKGIucmVsYXRvKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0b3Muc3BsaWNlKHJlbGF0b3MuaW5kZXhPZignZGlzcGxheScpLDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBrPTA7azxyZWxhdG9zLmxlbmd0aDtrKyspew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkPXJlbGF0b3Nba107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYi5yZWxhdG8uZGlzcGxheSA9IHNob3c7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoYyl7DQogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImdbZWRcXDp0b2d0b3BpY2lkPSciK2ErIiddIikuc3R5bGUuZGlzcGxheT1zaG93Ow0KICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQogICAgICAgICAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKChiLmNhbGx8fGIuYm91bmRhcnl8fGIuc3VtbWFyeSkmJmM9PT0ncGx1cycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdyx0cnVlKQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCiAgICAgICAgICAgICAgICAgICAgdXRkKGIsYSxzaG93LHRydWUpDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChiLnN1bW1hcnkmJiFjKSB7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGIuYm91bmRhcnkmJiFjKSB7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBpZihvYmouc3VtbWFyeSl7DQogICAgICAgIHZhciBzdW1tYXJ5cz1PYmplY3Qua2V5cyhvYmouc3VtbWFyeSk7DQogICAgICAgIGlmKChjaGVja0lEIT09b2JqJiYob2JqLnRvZ3R5cGU9PT0nbWludXMnfHwhb2JqLnRvZ3R5cGUpKXx8Y2hlY2tJRD09PW9iail7DQogICAgICAgICAgICBmb3IodmFyIGk9MDtpPHN1bW1hcnlzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPXN1bW1hcnlzW2ldLnNsaWNlKDEpOw0KCQkJCXZhciBvc3AgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5nZXRBdHRyaWJ1dGUoJ2VkOnBhcmVudGlkJyk7DQogICAgICAgICAgICAgICAgaWYob3NwLm1hdGNoKC9cLC8pKXsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG9zcGEgPSBvc3Auc3BsaXQoJywnKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG9zcEw9MDsNCg0KICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGo9MDtqPG9zcGEubGVuZ3RoO2orKyl7DQogICAgICAgICAgICAgICAgICAgICAgICBpZihzaG93ID09ICdub25lJyl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3NwYVtqXSkuc3R5bGUuZGlzcGxheSAhPSAnbm9uZScpew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3NwTCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5ICE9ICdub25lJyl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvc3BMKys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGlmKG9zcEwgIT09IG9zcGEubGVuZ3RoKXsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHZhciBiPW9iai5zdW1tYXJ5W3N1bW1hcnlzW2ldXTsNCiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhhKTsNCiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5PXNob3c7DQovLyAgICAgICAgICAgICAgICBpZihjKXsNCi8vICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6dG9ndG9waWNpZD0nIithKyInXSIpLnN0eWxlLmRpc3BsYXk9c2hvdzsNCi8vICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQovLyAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLHNob3cpDQovLyAgICAgICAgICAgICAgICAgICAgfQ0KLy8gICAgICAgICAgICAgICAgICAgIGlmIChiLmNhbGwmJmM9PT0ncGx1cycpIHsNCi8vICAgICAgICAgICAgICAgICAgICAgICAgdXRkKGIsc2hvdyx0cnVlKQ0KLy8gICAgICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCi8vICAgICAgICAgICAgICAgICAgICB1dGQoYixzaG93LHRydWUpDQovLyAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoT2JqZWN0LmtleXMoYikubGVuZ3RoIT09MCl7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgaWYob2JqLmJvdW5kYXJ5KXsNCiAgICAgICAgdmFyIGJvdW5kYXJ5cz1PYmplY3Qua2V5cyhvYmouYm91bmRhcnkpOw0KICAgICAgICBpZihjaGVja0lEIT09b2JqKXsNCiAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8Ym91bmRhcnlzLmxlbmd0aDtpKyspew0KICAgICAgICAgICAgICAgIHZhciBhPWJvdW5kYXJ5c1tpXS5zbGljZSgxKTsNCiAgICAgICAgICAgICAgICB2YXIgYj1vYmouYm91bmRhcnlbYm91bmRhcnlzW2ldXTsNCiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhhKTsNCiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChhKS5zdHlsZS5kaXNwbGF5PXNob3c7DQovLyAgICAgICAgICAgICAgICBpZihjKXsNCi8vICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6dG9ndG9waWNpZD0nIithKyInXSIpLnN0eWxlLmRpc3BsYXk9c2hvdzsNCi8vICAgICAgICAgICAgICAgICAgICBpZihjPT09J21pbnVzJyl7DQovLyAgICAgICAgICAgICAgICAgICAgICAgIHV0ZChiLHNob3cpDQovLyAgICAgICAgICAgICAgICAgICAgfQ0KLy8gICAgICAgICAgICAgICAgICAgIGlmIChiLmNhbGwmJmM9PT0ncGx1cycpIHsNCi8vICAgICAgICAgICAgICAgICAgICAgICAgdXRkKGIsc2hvdyx0cnVlKQ0KLy8gICAgICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIH0NCi8vICAgICAgICAgICAgICAgIGlmKGIuY2FsbCYmIWMpIHsNCi8vICAgICAgICAgICAgICAgICAgICB1dGQoYixzaG93LHRydWUpDQovLyAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYoT2JqZWN0LmtleXMoYikubGVuZ3RoIT09MCl7DQogICAgICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdykNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQogICAgaWYoIW9jJiZvYmouY2hpbGQpIHsNCiAgICAgICAgdmFyIGNoaWxkcyA9IE9iamVjdC5rZXlzKG9iai5jaGlsZCk7DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgYSA9IGNoaWxkc1tpXS5zbGljZSgxKTsNCiAgICAgICAgICAgIHZhciBiID0gb2JqLmNoaWxkW2NoaWxkc1tpXV07DQogICAgICAgICAgICB2YXIgYyA9IGIudG9ndHlwZTsNCiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGEpLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KCQkJdmFyIHRTUGF0aCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInBhdGhbZWRcXDp0b3N1cGVyaWQ9JyIrYSsiJ10iKTsNCiAgICAgICAgICAgIGlmKHRTUGF0aCl7DQogICAgICAgICAgICAgICAgdFNQYXRoLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgfQ0KCQkJdmFyIG5vdGVUaXAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJnW2VkXFw6bm90ZXRvPSciK2ErIiddIik7DQogICAgICAgICAgICBpZihub3RlVGlwKXsNCiAgICAgICAgICAgICAgICBub3RlVGlwLnN0eWxlLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGIucmVsYWZyb20mJiFjKXsNCiAgICAgICAgICAgICAgICBpZihiLnJlbGFmcm9tLmRpc3BsYXkhPT0gc2hvdyl7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWxhZnJvbXM9T2JqZWN0LmtleXMoYi5yZWxhZnJvbSk7DQogICAgICAgICAgICAgICAgICAgIHJlbGFmcm9tcy5zcGxpY2UocmVsYWZyb21zLmluZGV4T2YoJ2Rpc3BsYXknKSwxKTsNCiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBrPTA7azxyZWxhZnJvbXMubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhZnJvbXNba107DQogICAgICAgICAgICAgICAgICAgICAgICBleHRyYVJlbGFbZF0uaXNDPXRydWU7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYi5yZWxhZnJvbS5kaXNwbGF5ID0gc2hvdzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5yZWxhdG8mJiFjKXsNCiAgICAgICAgICAgICAgICBpZihiLnJlbGF0by5kaXNwbGF5IT09IHNob3cpew0KICAgICAgICAgICAgICAgICAgICB2YXIgcmVsYXRvcz1PYmplY3Qua2V5cyhiLnJlbGF0byk7DQogICAgICAgICAgICAgICAgICAgIHJlbGF0b3Muc3BsaWNlKHJlbGF0b3MuaW5kZXhPZignZGlzcGxheScpLDEpOw0KICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGs9MDtrPHJlbGF0b3MubGVuZ3RoO2srKyl7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZD1yZWxhdG9zW2tdOw0KICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFSZWxhW2RdLmlzQz10cnVlOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGIucmVsYXRvLmRpc3BsYXkgPSBzaG93Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChjKSB7DQogICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiZ1tlZFxcOnRvZ3RvcGljaWQ9JyIgKyBhICsgIiddIikuc3R5bGUuZGlzcGxheSA9IHNob3c7DQogICAgICAgICAgICAgICAgaWYgKGMgPT09ICdtaW51cycpIHsNCiAgICAgICAgICAgICAgICAgICAgdXRkKGIsYSxzaG93KQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoKGIuY2FsbHx8Yi5ib3VuZGFyeXx8Yi5zdW1tYXJ5KSYmYz09PSdwbHVzJykgew0KICAgICAgICAgICAgICAgICAgICB1dGQoYixhLHNob3csdHJ1ZSkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5jYWxsJiYhYykgew0KICAgICAgICAgICAgICAgIHV0ZChiLGEsc2hvdyx0cnVlKQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKGIuc3VtbWFyeSYmIWMpIHsNCiAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoYi5ib3VuZGFyeSYmIWMpIHsNCiAgICAgICAgICAgICAgICB1dGQoYixhLHNob3cpDQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQp9DQoNCmZ1bmN0aW9uIGV4dHJhUmVsYUZpbigpIHsNCiAgICB2YXIgZXh0cmFrZXlzPU9iamVjdC5rZXlzKGV4dHJhUmVsYSk7DQogICAgZm9yKHZhciBpPTA7aTxleHRyYWtleXMubGVuZ3RoO2krKyl7DQogICAgICAgIHZhciBleHRyYU9iaj1leHRyYVJlbGFbZXh0cmFrZXlzW2ldXTsNCiAgICAgICAgaWYoZXh0cmFPYmouaXNDID09PSB0cnVlKXsNCiAgICAgICAgICAgIHZhciBmc2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai5mcm9taWQpLnN0eWxlLmRpc3BsYXkgIT09J25vbmUnPyB0cnVlOiBmYWxzZTsNCiAgICAgICAgICAgIHZhciB0c2hvdz1kb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai50b2lkKS5zdHlsZS5kaXNwbGF5ICE9PSdub25lJz8gdHJ1ZTogZmFsc2U7DQogICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChleHRyYU9iai5pZCkuc3R5bGUuZGlzcGxheT1mc2hvdyAmJiB0c2hvdz8gJ2Jsb2NrJzogJ25vbmUnOw0KICAgICAgICAgICAgZXh0cmFSZWxhW2V4dHJha2V5c1tpXV0uaXNDID0gZmFsc2U7DQogICAgICAgIH0NCiAgICB9DQp9'))</script>
  </body>
</html>
